Core data UIManagedDocument-如何处理UIDocumentStateSavingError?
我正在开发我的第一个iCloud应用程序。工作一段时间后,由于“UIDocumentStateSavingError”,应用程序无法再访问UIManagedDocument。有没有办法真正找出发生了什么错误 这是我创建UIManagedDocument的代码:Core data UIManagedDocument-如何处理UIDocumentStateSavingError?,core-data,icloud,uimanageddocument,Core Data,Icloud,Uimanageddocument,我正在开发我的第一个iCloud应用程序。工作一段时间后,由于“UIDocumentStateSavingError”,应用程序无法再访问UIManagedDocument。有没有办法真正找出发生了什么错误 这是我创建UIManagedDocument的代码: dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ iCloudURL = [[NSFileManager defaul
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
iCloudURL = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
if (iCloudURL == nil) {
dispatch_async(dispatch_get_main_queue(), ^{
[self iCloudNotAvailable];
});
return;
}
iCloudDocumentsURL = [iCloudURL URLByAppendingPathComponent:@"Documents"];
iCloudCoreDataLogFilesURL = [iCloudURL URLByAppendingPathComponent:@"TransactionLogs"];
NSURL *url = [iCloudDocumentsURL URLByAppendingPathComponent:@"CloudDatabase"];
iCloudDatabaseDocument = [[UIManagedDocument alloc] initWithFileURL:url];
NSMutableDictionary *options = [NSMutableDictionary dictionary];
NSString *name = [iCloudDatabaseDocument.fileURL lastPathComponent];
[options setObject:name forKey:NSPersistentStoreUbiquitousContentNameKey];
[options setObject:iCloudCoreDataLogFilesURL forKey:NSPersistentStoreUbiquitousContentURLKey];
iCloudDatabaseDocument.persistentStoreOptions = options;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(documentContentsChanged:) name:NSPersistentStoreDidImportUbiquitousContentChangesNotification object:iCloudDatabaseDocument.managedObjectContext.persistentStoreCoordinator];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(documentStateChanged:) name:UIDocumentStateChangedNotification object:iCloudDatabaseDocument];
if ([[NSFileManager defaultManager] fileExistsAtPath:[iCloudDatabaseDocument.fileURL path]]) {
// This is true, the document exists.
if (iCloudDatabaseDocument.documentState == UIDocumentStateClosed) {
[iCloudDatabaseDocument openWithCompletionHandler:^(BOOL success) {
if (success) {
dispatch_async(dispatch_get_main_queue(), ^{
[self documentConnectionIsReady];
});
} else {
dispatch_async(dispatch_get_main_queue(), ^{
[self connectionError:iCloudConnectionErrorFailedToOpen];
});
}
}];
} else if (iCloudDatabaseDocument.documentState == UIDocumentStateNormal) {
...
}
} else {
...
}
});
该文档已存在,因此对该文档调用openWithCompletionHandler:。此操作失败,并触发UIDocumentStateChangedNotification,显示文档状态为5:
UIDocumentStateClosed和
UIDocumentStateSavingError
在此之后,将调用完成块。从这里出发的正确方法是什么?有没有办法找出哪里出了问题,发生了什么样的错误
我试图在完成块中重新打开文档,但结果相同
我想我可以通过删除文件并重新创建来解决这个问题。但这显然不是一个选项,一旦应用程序将在商店中。我想知道出了什么问题,并给用户一个合适的方法来处理这个问题
我已经在这里检查了处理UIDocumentStateSavingError的其他问题(这些问题并不多),但似乎不适用于这里的问题
你知道我怎样才能找出问题所在吗?我无法相信API会告诉您“保存过程中出现了问题,但我不会告诉您是什么!”您可以在完成处理程序中查询documentState。不幸的是,如果您想要得到确切的错误,唯一的方法是子类化并重写handleError:UserInteractionAllowed: 也许像这样的东西会有帮助(不用编译器徒手输入) 然后你可以这样创造它
iCloudDatabaseDocument = [[UIManagedDocument alloc] initWithFileURL:url];
[iCloudDatabaseDocument openWithCompletionHandler:^(BOOL success) {
if (success) {
dispatch_async(dispatch_get_main_queue(), ^{
[self documentConnectionIsReady];
});
} else {
dispatch_async(dispatch_get_main_queue(), ^{
[self connectionError:iCloudConnectionErrorFailedToOpen
withError:iCloudDatabaseDocument.lastError];
});
}
}];
在完成处理程序中使用它,如下所示
iCloudDatabaseDocument = [[UIManagedDocument alloc] initWithFileURL:url];
[iCloudDatabaseDocument openWithCompletionHandler:^(BOOL success) {
if (success) {
dispatch_async(dispatch_get_main_queue(), ^{
[self documentConnectionIsReady];
});
} else {
dispatch_async(dispatch_get_main_queue(), ^{
[self connectionError:iCloudConnectionErrorFailedToOpen
withError:iCloudDatabaseDocument.lastError];
});
}
}];
基于@JodyHagins优秀的代码片段,我创建了一个UIDocument子类
@interface SSDocument : UIDocument
- (void)openWithSuccess:(void (^)())successBlock
failureBlock:(void (^)(NSError *error))failureBlock;
@end
@interface SSDocument ()
@property (nonatomic, strong) NSError *lastError;
@end
@implementation SSDocument
- (void)handleError:(NSError *)error userInteractionPermitted:(BOOL)userInteractionPermitted {
self.lastError = error;
[super handleError:error userInteractionPermitted:userInteractionPermitted];
}
- (void)clearLastError {
self.lastError = nil;
}
- (void)openWithSuccess:(void (^)())successBlock failureBlock:(void (^)(NSError *error))failureBlock {
NSParameterAssert(successBlock);
NSParameterAssert(failureBlock);
[self clearLastError];
[self openWithCompletionHandler:^(BOOL success) {
if (success) {
successBlock();
} else {
NSError *error = self.lastError;
[self clearLastError];
failureBlock(error);
}
}];
}
@end