如何在iOS中捕获iCloud异常?

时间:2014-02-07 10:44:42

标签: ios objective-c exception icloud

我的一个iOS应用程序使用Core Data和iCloud一段时间了。虽然这种方法在大多数情况下都能很好地工作,但每个知道都会出现问题和崩溃。问题:我无法通过捕获异常来解决这些崩溃,因为我不知道在哪里这样做。

崩溃应用程序的异常的最新示例是:

2014-02-07 10:23:45.118 MyApp[1410:3707] -[PFUbiquitySwitchboardEntryMetadata setUseLocalStorage:](754): CoreData: Ubiquity:  mobile~5508B01E-F77F-4AF1-88DE-2E2F8DC55932:MyAppCloudDB
Using local storage: 1

2014-02-07 10:23:45.892 MyApp[1410:3707] -[PFUbiquitySwitchboardEntryMetadata setUseLocalStorage:](754): CoreData: Ubiquity:  mobile~5508B01E-F77F-4AF1-88DE-2E2F8DC55932:MyAppCloudDB
Using local storage: 0

2014-02-07 10:24:28.632 MyApp[1410:1803] -[_PFUbiquityRecordImportOperation main](731): CoreData: Ubiquity:  Error importing transaction log: <PFUbiquityTransactionLog: 0x16177920>
transactionLogLocation: <PFUbiquityLocation: 0x160c3e80>: /var/mobile/Library/Mobile Documents/M889WYL2LY~com~example~MyApp/MyAppTransactionLogs/User~37B9682D-CED2-5F79-AF06-1FE99E7DEE9E/MyAppCloudDB/SZPp~RKudtVxEBMJzTVTupTv0WjG6i~o9Vj54dlknjc=/8AB09D17-5856-49B9-BE4C-A56451FB1EF4.1.cdt
transactionNumber: 34
, exception: *** setObjectForKey: key cannot be nil
User Info: (null)

2014-02-07 10:24:28.661 MyApp[1410:1803] -[_PFUbiquityRecordsImporter operation:failedWithError:](1003): CoreData: Ubiquity:  Import operation encountered an error: Error Domain=NSCocoaErrorDomain Code=134060 "The operation couldn’t be completed. (Cocoa error 134060.)" UserInfo=0x162a8b20 {exception=*** setObjectForKey: key cannot be nil}
userInfo: {
exception = "*** setObjectForKey: key cannot be nil";
}. While trying to import the log file at the URL: <PFUbiquityTransactionLog: 0x16177920>
transactionLogLocation: <PFUbiquityLocation: 0x160c3e80>: /var/mobile/Library/Mobile Documents/M889WYL2LY~com~example~MyApp/MyAppTransactionLogs/User~37B9682D-CED2-5F79-AF06-1FE99E7DEE9E/MyAppCloudDB/SZPp~RKudtVxEBMJzTVTupTv0WjG6i~o9Vj54dlknjc=/8AB09D17-5856-49B9-BE4C-A56451FB1EF4.1.cdt
transactionNumber: 34

2014-02-07 10:24:28.686 MyApp[1410:1803] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** setObjectForKey: key cannot be nil'
*** First throw call stack:

(0x30b47e83 0x3aea46c7 0x30a82ecb 0x309dd0cb 0x3099f061 0x309a1841 0x31476aa5 0x3151a96d 0x3b38de7b 0x3b38af93 0x3b38e745 0x3b38e9c5 0x3b4b8dff 0x3b4b8cc4)
libc++abi.dylib: terminating with uncaught exception of type NSException

似乎事务日志有问题。当然,我想解决问题,让应用程序保持运行而不是崩溃。因此,我必须能够捕获并处理异常。但是我怎么能这样做呢?

我甚至不知道这种例外的来源。我假设它是由UIManagedDocument或UIManagedObjectContext类引发的,但我不确定。

即使我知道异常来自其中一个类,我仍然不知道如何捕获它。某些iCloud相关类在导入事务日志时在后台线程中抛出异常。我在代码中的所有内容都是对UIManagedDocument实例的引用。当然,我可以在Try-Catch块中包装对这个实例的每次调用,但是当我使用/调用这个实例但是当对象自己做一些工作时,不会抛出异常。

甚至可以捕获这些异常吗?

即使无法捕获并解决异常,也很高兴知道异常被抛出。这至少让我有机会在下次启动应用程序时处理问题(向用户显示消息,断开与iCloud的连接等)。

那么,处理这些异常的最佳方法是什么?

非常感谢!

2 个答案:

答案 0 :(得分:0)

我认为你不太可能找到一种方法来捕捉异常。毫无疑问,它们是后台线程,在调用堆栈中没有任何方法。你可能会调用其中一种Apple方法,但它变得非常难看,而且无论如何都不允许在App Store中使用。

不幸的是,Core Data + iCloud的不透明度是对它的一个分数。你不知道它应该如何工作,当它像这样失败时,你真的没有追索权。

我建议提交雷达,但你可能希望的最好的是在iOS 8中修复它。

值得考虑其他同步框架,例如TICDSEnsembles,它们都适用于iCloud。优点是你至少拥有源代码,可以看出出现了什么问题,并且经常在几小时内得到修复。

(披露:我创立了Ensembles项目)

答案 1 :(得分:0)

如果您正在使用UIManagedDocument,则需要对其进行子类化并覆盖一些方法以获取错误。特别是这两个

- (id)contentsForType:(NSString *)typeName error:(NSError *__autoreleasing *)outError
{
    LOG(@"Auto-Saving Document");
    return [super contentsForType:typeName error:outError];
}

- (void)handleError:(NSError *)error userInteractionPermitted:(BOOL)userInteractionPermitted
{
    FLOG(@" error: %@", error.localizedDescription);
    NSArray* errors = [[error userInfo] objectForKey:NSDetailedErrorsKey];
    if(errors != nil && errors.count > 0) {
        for (NSError *error in errors) {
            FLOG(@" Error: %@", error.userInfo);
        }
    } else {
        FLOG(@" error.userInfo = %@", error.userInfo);
    }
}

不确定这些是否会发现您的具体错误。

更多关于Core Data和iCloud集成的信息。

http://ossh.com.au/design-and-technology/software-development/