【问题标题】:UIManagedDocument - How to deal with UIDocumentStateSavingError?UIManagedDocument - 如何处理 UIDocumentStateSavingError?
【发布时间】:2012-04-18 10:42:33
【问题描述】:

我正在开发我的第一个 iCloud 应用程序。工作一段时间后,由于“UIDocumentStateSavingError”,应用程序无法再访问 UIManagedDocument。有什么方法可以真正找出发生了什么错误?

这是我创建 UIManagedDocument 的代码:

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 会告诉你“保存过程中出了点问题,但我不会告诉你什么!”

【问题讨论】:

    标签: core-data icloud uimanageddocument


    【解决方案1】:

    您可以在完成处理程序中查询 documentState。不幸的是,如果您想要确切的错误,获得它的唯一方法是子类化并覆盖 handleError:userInteractionPermitted:

    也许这样的事情会有所帮助(在没有编译器的情况下徒手键入)...

    @interface MyManagedDocument : UIManagedDocument
     - (void)handleError:(NSError *)error
             userInteractionPermitted:(BOOL)userInteractionPermitted;
    @property (nonatomic, strong) NSError *lastError;
    @end
    
    @implementation MyManagedDocument
    @synthesize lastError = _lastError;
     - (void)handleError:(NSError *)error
             userInteractionPermitted:(BOOL)userInteractionPermitted
    {
        self.lastError = error;
        [super handleError:error
               userInteractionPermitted:userInteractionPermitted];
    }
    @end
    

    然后你可以像这样创建它......

    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];
                    });
                }
            }];                    
    

    【讨论】:

      【解决方案2】:

      基于@JodyHagins 优秀的sn-p,我做了一个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
      

      【讨论】:

        猜你喜欢
        • 2011-12-24
        • 1970-01-01
        • 2013-08-28
        • 1970-01-01
        • 2013-12-24
        • 1970-01-01
        • 2012-05-06
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多