2012-10-05 29 views
3

我创造与iCloud的支持,新的UIManagedDocument如下:可以创建,但不开放,与iCloud的支持UIManagedDocument

  1. 的Alloc,并与当地的沙盒URL初始化
  2. 设置持久性存储选项,支持iCloud :ubiquitousContentNameKey和ubiquitousContentURL。我唯一生成的名称和URL指向我的ubiquityContainer/CoreData。
  3. 使用UIManagedDocument的saveToURL方法在本地保存到沙箱。
  4. 在完成处理程序中,使用FileManager的setUbiquitous方法移至iCloud。

到目前为止,这个舞蹈的作品。 (好吧,有点)。在我调用setUbiquitous之后,我得到一个错误,说它并不成功,但文档移动到了云中。完成后,我在云端有一个新文档。这似乎是一个错误,因为我已经能够用别人的代码复制它。

我实际上是在一个“文档视图控制器”中生成这个文档,它列出了云中的所有文档。所以,当这个新文档的最终完成处理程序完成时,由于NSMetadataQuery的原因,它显示在表视图中。到目前为止,我认为非常标准的用法。

要编辑文档,用户点击并进入“单视图文档视图控制器”。

在此视图控制器中,我需要“重新打开”所选文档,以便用户可以对其进行编辑。

所以我经过一系列的步骤再次:

  1. 分配/初始化一个UIManagedDocument与fileURL - 这个时候,URL是从云。
  2. 使用相同的设置,设置我的永久存储选项,与上面的步骤2相同。

现在,我尝试了第3步,即从磁盘打开文档,但失败。文档处于“Closed | SavingError”状态,尝试打开失败。

有没有人知道为什么我的文档会创建好,移动到云确定,但然后无法打开立即后续尝试? (真的,在应用程序启动的尝试 - 见下文)。具体来说,什么会创建一个UIManagedDocument实例,但处于一个封闭的,不可打开的状态?

有趣的是,如果我退出应用程序并重新启动,我可以点击并重新加载文档并对其进行编辑。

偶尔我可以创建,然后打开并编辑非常简短的内容,比如插入一个managed对象,然后进入这个close |保存错误状态。

错误信息:

我子类UIManagedDocument并推翻了-handleError:方法,试图获得更多的信息,这里是我得到了什么(有一些其他的调试日志,我把沿):

2012-10-05 14:57:06.000基础[23687:907]单个文档视图控制器视图未加载。文档:fileURL:file:// localhost/private/var/mobile/Library/Mobile%20Documents/7PB5426XF4〜com〜howlin〜MyApp/Documents/New%20Document%2034/documentState:[Closed]

2012-10 -05 14:57:06.052 MyApp [23687:907]文档状态已更改。当前状态:5 fileURL:file:// localhost/private/var/mobile/Library/Mobile%20Documents/7PB5426XF4〜com〜howlin〜MyApp/Documents/New%20Document%2034/documentState:[Closed | SavingError]

2012-10-05 14:57:06.057 Foundations [23687:5303] UIManagedDocument错误:商店名称:New Document 34已在使用中。 商店网址:file://localhost/private/var/mobile/Library/Mobile%20Documents/7PB5426XF4~com~howlin~MyApp/Documents/New%20Document%2034/StoreContent.nosync/persistentStore In Use Store URL:file ://localhost/var/mobile/Applications/D423F5FF-4B8E-4C3E-B908-11824D70FD34/Documents/New%20Document%2034/StoreContent.nosync/persistentStore

2012-10-05 14:57:06.059 MyApp [ \ n \ tStore URL:file:// localhost/private/var/mobile/Library/Mobile%20Documents/7PB5426XF4〜com〜howlin 〜MyApp/Documents/New%20Document%2034/StoreContent.nosync/persistentStore \ n \ tIn Use Store URL:file:// localhost/var/mobile/Applications/D423F5FF-4B8E-4C3E-B908-11824D70FD34/Documents/New% 20Document%2034/StoreContent.nosync/persiste ntStore \ n“个; NSPersistentStoreUbiquitousContentNameKey =“New Document 34”; }

该错误似乎认为我创建了一个商店,在随后的开放已经存在。我现在应该在第二次开放时在持久存储上设置这些iCloud选项吗?我已经尝试过这种方法,但它也没有工作。

我已经研究了UIManagedDocument的斯坦福讲座,并没有看到我做错了什么。

这里是我的方法来创建文档并移动到云:

- (void) testCreatingICloudDocWithName:(NSString*)name 
{ 

    NSURL* cloudURL = [self.docManager.iCloudURL URLByAppendingPathComponent:name isDirectory:YES]; 

    NSURL* fileURL = [self.docManager.localURL URLByAppendingPathComponent:name]; 


    self.aWriting = [[FNFoundationDocument alloc] initWithFileURL:fileURL]; 


    [self setPersistentStoreOptionsInDocument:self.aWriting]; 

    [self.aWriting saveToURL:fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) { 
     if (success == YES) { 

      dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ 
       //create file coordinator 
       //move document to icloud 

       NSFileCoordinator* fileCoordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil]; 
       NSError* coorError = nil; 
       [fileCoordinator coordinateWritingItemAtURL:cloudURL options:NSFileCoordinatorWritingForReplacing error:&coorError byAccessor:^(NSURL *newURL) { 

        if (coorError) { 
         NSLog(@"Coordinating writer error: %@", coorError); 
        } 

        NSFileManager* fm = [NSFileManager defaultManager]; 
        NSError* error = nil; 
        NSLog(@"Before set ubiq"); 
        [fm setUbiquitous:YES itemAtURL:fileURL destinationURL:newURL error:&error]; 
        if (!error) { 
         NSLog(@"Set ubiquitous successfully."); 
        } 
        else NSLog(@"Error saving to cloud. Error: %@", error); 


        NSLog(@"State of Doc after error saving to cloud: %@", self.aWriting); 
       }]; 



      }); 

     } 
    }]; 

} 

这里就是我的的iCloud设置在persistentStore选项:

- (void)setPersistentStoreOptionsInDocument:(FNDocument *)theDocument 
{ 
    NSMutableDictionary *options = [NSMutableDictionary dictionary]; 
    [options setObject:[NSNumber numberWithBool:YES] forKey:NSMigratePersistentStoresAutomaticallyOption]; 
    [options setObject:[NSNumber numberWithBool:YES] forKey:NSInferMappingModelAutomaticallyOption]; 

    [options setObject:[theDocument.fileURL lastPathComponent] forKey:NSPersistentStoreUbiquitousContentNameKey]; 
    NSURL* coreDataLogDirectory = [self.docManager.coreDataLogsURL URLByAppendingPathComponent:[theDocument.fileURL lastPathComponent]]; 
    NSLog(@"Core data log dir: %@", coreDataLogDirectory); 
    [options setObject:coreDataLogDirectory forKey:NSPersistentStoreUbiquitousContentURLKey]; 

    theDocument.persistentStoreOptions = options; 
} 

这里的地方我试图重新打开它:

- (void) prepareDocForUse 
{ 

    NSURL* fileURL = self.singleDocument.fileURL; 

    if (![[NSFileManager defaultManager] fileExistsAtPath:[fileURL path]]) { 
     NSLog(@"File doesn't exist"); 
      } 
    else if (self.singleDocument.documentState == UIDocumentStateClosed) { 
     // exists on disk, but we need to open it 
     [self.singleDocument openWithCompletionHandler:^(BOOL success) { 
      if (!success) { 
       NSError* error; 
       [self.singleDocument handleError:error userInteractionPermitted:NO]; 
      } 
      [self setupFetchedResultsController]; 
     }]; 
    } else if (self.singleDocument.documentState == UIDocumentStateNormal) { 
     // already open and ready to use 
     [self setupFetchedResultsController]; 
    } 

} 
+0

这是在模拟器上?如果是,哪个iOS版本?我和其他人在Xcode中使用派生的斯坦福代码的iOS 5.1模拟器有非常奇怪的问题 – brainray

+0

这是设备上的iOS 6。不幸的是,你不能在模拟器上测试iCloud。 –

+0

我认为这是setUbiquitous方法。无论苹果公司的文档如何,我认为使用UIManagedDocument时没有必要。除非有人可以使用ubiquityContainer URL解释setUbiquitous和saveToURL之间的区别?当我将saveToURL正确保存到iCloud时,它似乎可以正常工作。 –

回答

0

你最近是否测试过各种版本的iOS?尝试将保存的文档的标题更改为“新建文档34”以外的内容,但我遇到了同样的问题,我认为这与使用相同文档网址从应用程序的不同sdk编译中保存的冲突文档有关。

0

我的目标是iOS7,我使用单个UIManagedDocument作为我的应用程序数据库,其目标是更好地集成CoreData和iCloud,正如Apple在其文档中所建议的那样。我有同样的问题,我用下面的代码解决。

由于我写了它,我移动了UIManagedDocument的惰性实例中的PSC选项设置。

我的原始代码创建,关闭,然后使用成功标准函数的回调重新打开文档。我在Erika Sadun的一本书中找到它。一切似乎都没问题,但我无法重新打开刚刚创建,然后关闭的文档,因为它处于“储蓄错误”状态。我失去了一周的时间,我无法理解我做错了什么,因为直到重新开放一切都是完美的。

以下代码完美地适用于我的iPhone5和iPad3。

尼古拉

-(void) fetchDataWithBlock: (void (^) (void)) fetchingDataBlock 
{ 

    //If the CoreData local file exists then open it and perform the query 
    if([[NSFileManager defaultManager] fileExistsAtPath:[self.managedDocument.fileURL path]]){ 
     NSLog(@"The CoreData local file in the application sandbox already exists."); 

     if (self.managedDocument.documentState == UIDocumentStateNormal){ 
      NSLog(@"The CoreData local file it's in Normal state. Fetching data."); 
      fetchingDataBlock(); 
     }else if (self.managedDocument.documentState == UIDocumentStateClosed){ 
      NSLog(@"The CoreData local file it's in Closed state. I am opening it."); 

      [self.managedDocument openWithCompletionHandler:^(BOOL success) { 
       if(success){ 
        NSLog(@"SUCCESS: The CoreData local file has been opened succesfully. Fetching data."); 
        fetchingDataBlock(); 
       }else{ 
        NSLog(@"ERROR: Can't open the CoreData local file. Can't fetch the data."); 
        NSLog(@"%@", self.managedDocument); 
        return; 
       } 
      }]; 
     }else{ 
      NSLog(@"ERROR: The CoreData local file has an unexpected documentState: %@", self.managedDocument); 
     } 
    }else{ 
     NSLog(@"The CoreData local file in the application sandbox did not exist."); 
      NSLog(@"Setting the UIManagedDocument PSC options."); 
     [self setPersistentStoreOptionsInDocument:self.managedDocument]; 

     //Create the Core Data local File 
     [self.managedDocument saveToURL:self.managedDocument.fileURL 
         forSaveOperation:UIDocumentSaveForCreating 
         completionHandler:^(BOOL success) { 

      if(success){ 

       NSLog(@"SUCCESS: The CoreData local file has been created. Fetching data."); 
       fetchingDataBlock(); 

      }else{ 
       NSLog(@"ERROR: Can't create the CoreData local file in the application sandbox. Can't fetch the data."); 
       NSLog(@"%@", self.managedDocument); 
       return; 
      } 

     }]; 

    } 
} 
相关问题