iphone - iPhone Core Data "Production" Error handling




3 Answers

لا أحد سيعرض لك رمز الإنتاج لأنه يعتمد 100٪ على التطبيق الخاص بك وحيث يحدث الخطأ.

أنا شخصياً أضع بياناً مؤكداً هناك لأن 99.9٪ من الوقت سيحدث هذا الخطأ في التطوير وعندما تقوم بإصلاحه هناك من المستبعد جداً أن تشاهده في الإنتاج.

بعد التأكيد ، سأقدم تنبيهًا للمستخدم ، أخبرهم بحدوث خطأ غير قابل للاسترداد وأن التطبيق سيخرج. يمكنك أيضًا وضع دعاية مغالية فيها يطالبهم بالاتصال بالمطور بحيث يمكنك تتبع ذلك.

بعد ذلك سأترك الإجهاض () هناك حيث سيؤدي إلى "تعطل" التطبيق وإنشاء تتبع مكدس يمكنك استخدامه في وقت لاحق لتعقب المشكلة.

لقد رأيت في مثال التعليمة البرمجية المقدمة من قبل مراجع Apple لكيفية التعامل مع أخطاء Core Data. أي:

NSError *error = nil;
if (![context save:&error]) {
/*
 Replace this implementation with code to handle the error appropriately.

 abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. If it is not possible to recover from the error, display an alert panel that instructs the user to quit the application by pressing the Home button.
 */
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}

لكن لا توجد أي أمثلة لكيفية تنفيذها.

هل لدى أي شخص (أو يمكن أن يشير لي في اتجاه) بعض رمز "الإنتاج" الفعلي الذي يوضح الطريقة المذكورة أعلاه.

شكرا مقدما ، مات




لقد وجدت وظيفة الحفظ الشائعة هذه حلاً أفضل بكثير:

- (BOOL)saveContext {
    NSError *error;
    if (![self.managedObjectContext save:&error]) {
        DDLogError(@"[%@::%@] Whoops, couldn't save managed object context due to errors. Rolling back. Error: %@\n\n", NSStringFromClass([self class]), NSStringFromSelector(_cmd), error);
        [self.managedObjectContext rollback];
        return NO;
    }
    return YES;
}

عندما يفشل الحفظ ، سيؤدي ذلك إلى استرجاع NSManagedObjectContext مما يعني أنه سيقوم بإعادة تعيين كافة التغييرات التي تم إجراؤها في السياق منذ الحفظ الأخير . لذلك عليك أن تحرص بعناية على الاستمرار في التغييرات باستخدام وظيفة حفظ أعلاه في وقت مبكر وبشكل منتظم قدر الإمكان حيث قد تفقد البيانات بسهولة.

لإدخال البيانات ، قد يكون هذا الخيار متغيرًا يسمح بتغيير التغييرات الأخرى:

- (BOOL)saveContext {
    NSError *error;
    if (![self.managedObjectContext save:&error]) {
        DDLogError(@"[%@::%@] Whoops, couldn't save. Removing erroneous object from context. Error: %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd), object.objectId, error);
        [self.managedObjectContext deleteObject:object];
        return NO;
    }
    return YES;
}

ملاحظة: أنا أستخدم CocoaLumberjack لتسجيل الدخول هنا.

أي تعليق على كيفية تحسين هذا هو أكثر من موضع ترحيب!

BR كريس




لقد صنعت نسخة سريعة من الإجابة المفيدة لـJohannesFahrenkrug والتي يمكن أن تكون مفيدة:

public func displayValidationError(anError:NSError?) -> String {
    if anError != nil && anError!.domain.compare("NSCocoaErrorDomain") == .OrderedSame {
        var messages:String = "Reason(s):\n"
        var errors = [AnyObject]()
        if (anError!.code == NSValidationMultipleErrorsError) {
            errors = anError!.userInfo[NSDetailedErrorsKey] as! [AnyObject]
        } else {
            errors = [AnyObject]()
            errors.append(anError!)
        }
        if (errors.count > 0) {
            for error in errors {
                if (error as? NSError)!.userInfo.keys.contains("conflictList") {
                    messages =  messages.stringByAppendingString("Generic merge conflict. see details : \(error)")
                }
                else
                {
                    let entityName = "\(((error as? NSError)!.userInfo["NSValidationErrorObject"] as! NSManagedObject).entity.name)"
                    let attributeName = "\((error as? NSError)!.userInfo["NSValidationErrorKey"])"
                    var msg = ""
                    switch (error.code) {
                    case NSManagedObjectValidationError:
                        msg = "Generic validation error.";
                        break;
                    case NSValidationMissingMandatoryPropertyError:
                        msg = String(format:"The attribute '%@' mustn't be empty.", attributeName)
                        break;
                    case NSValidationRelationshipLacksMinimumCountError:
                        msg = String(format:"The relationship '%@' doesn't have enough entries.", attributeName)
                        break;
                    case NSValidationRelationshipExceedsMaximumCountError:
                        msg = String(format:"The relationship '%@' has too many entries.", attributeName)
                        break;
                    case NSValidationRelationshipDeniedDeleteError:
                        msg = String(format:"To delete, the relationship '%@' must be empty.", attributeName)
                        break;
                    case NSValidationNumberTooLargeError:
                        msg = String(format:"The number of the attribute '%@' is too large.", attributeName)
                        break;
                    case NSValidationNumberTooSmallError:
                        msg = String(format:"The number of the attribute '%@' is too small.", attributeName)
                        break;
                    case NSValidationDateTooLateError:
                        msg = String(format:"The date of the attribute '%@' is too late.", attributeName)
                        break;
                    case NSValidationDateTooSoonError:
                        msg = String(format:"The date of the attribute '%@' is too soon.", attributeName)
                        break;
                    case NSValidationInvalidDateError:
                        msg = String(format:"The date of the attribute '%@' is invalid.", attributeName)
                        break;
                    case NSValidationStringTooLongError:
                        msg = String(format:"The text of the attribute '%@' is too long.", attributeName)
                        break;
                    case NSValidationStringTooShortError:
                        msg = String(format:"The text of the attribute '%@' is too short.", attributeName)
                        break;
                    case NSValidationStringPatternMatchingError:
                        msg = String(format:"The text of the attribute '%@' doesn't match the required pattern.", attributeName)
                        break;
                    default:
                        msg = String(format:"Unknown error (code %i).", error.code) as String
                        break;
                    }

                    messages = messages.stringByAppendingString("\(entityName).\(attributeName):\(msg)\n")
                }
            }
        }
        return messages
    }
    return "no error"
}`



Related