5

问题:我正在处理设备 A 上的 iCloud 文档,例如 iPod Touch。然后我更改设备 B 上文档的名称,例如我的 Mac(通过 Finder)。更改会上传到云端,并在设备 A 暂停后听到它。

进而:

  • 有时一切都很好-我通过更改的fileURL属性获取名称的更改,并可以相应地更新我的界面-文档继续按应有的方式运行
  • 有时,文档的 fileURL 会以如下形式返回:file://localhost/var/mobile/Library/Mobile%20Documents/.ubd/peer-43A0AEB6-84CE-283E-CA39-FCC4EF3BC8F8-v23/ftr/purg-012fdcfbe3b3bbce6e603fdfd2f000b2cb28649e95毫不奇怪,此文件不会保存。

谁能解释发生了什么以及如何解决它?

背景

  • 名称更改由 by 很好地接受NSMetadataQuery。因此,例如,我可以重命名未打开的文档,并且我的所有 iCloud 功能都可以正常工作。该问题似乎只发生在打开的文档中。

  • 其他 iCloud 功能运行良好,例如,我可以更改一台设备(例如我的 Mac)上的内容,然后检测并更新我在另一台设备(例如我的 iPod Touch)上打开相关 iCloud 文档的界面。

  • presentedItemDidMoveToURL:当我为我的 UIDocument 子类添加覆盖时,我第一次发现了这一点。覆盖可靠地拾取在云中进行的名称更改,例如在另一个设备上重命名文档。然后有时newURL 是重命名文档的最终预期 URL,即我可以从中提取新名称使用“lastPathComponent”,更新我的界面等的明智的东西。在其他情况下,newURL 是其他目录中的文档,带有最后一个路径组件以“purg-”开头,例如 purg-012fdcfbe3b3bbce6e603fdfd2f000b2cb28649e95。

    - (void) presentedItemDidMoveToURL:(NSURL *) newURL;
    {   
        [super presentedItemDidMoveToURL: newURL];
    
        if ([(id)[self delegate] respondsToSelector:@selector(documentNameChanged:)])
        {
            [[self delegate] documentNameChanged: self];
        }
    }
    
  • presentedItemDidMoveToURL:方法似乎不是问题的根本原因。例如,如果我根本不重写该方法,而是定期检查正在查看打开文档的 viewController,那么有时重命名后fileURL会返回新名称,有时会返回 `purg-.... .'. 所以问题似乎与如何处理重命名有关。

更新

正如 al_lea 指出的那样,这里的问题与accommodatePresentedItemDeletionWithCompletionHandler:. 扩展 al_lea 的答案,我将下面的代码添加到我的 UIDocument 子类中。这解决了这个问题。

    - (void) accommodatePresentedItemDeletionWithCompletionHandler: (void (^) (NSError *errorOrNil)) completionHandler
    {    
        PresentedDocument* presentedDocument = [self retain];
        [presentedDocument closeWithCompletionHandler: ^(BOOL success) {        
            NSError* error = nil;
            if (!success)
            {
                NSDictionary* userInfo = [NSDictionary dictionaryWithObjectsAndKeys:
                    @"Could not close document that is being deleted on another device",
                    NSLocalizedDescriptionKey, nil];
                    error = [NSError errorWithDomain: @"some_suitable_domain"
                                                code: 101
                                           userInfo: userInfo];
            }

        completionHandler(error);  // run the passed in completion handler (required)

        dispatch_async(dispatch_get_main_queue(), ^
        {
           [[NSNotificationCenter defaultCenter] postNotificationName: NOTIFY_presentedDocumentDeletedOnAnotherDevice
                                                               object: presentedDocument
                                                             userInfo: nil];

           [presentedDocument tidyUpAfterDelete];  // app specific tidy up
           [presentedDocument release];
       });
    }];
}

有了这个代码,就没有虚假和令人困惑的presentedItemDidMoveToURL: 调用,此外,相关对象可以监听其他设备上的删除通知。

4

1 回答 1

6

当在本地打开 UIDocument 并从远程设备中删除时,会出现这种类型的 URL:

file://localhost/var/mobile/Library/Mobile%20Documents/.ubd/peer-43A0AEB6-84CE-283E-CA39-FCC4EF3BC8F8-v23/ftr/purg-

您需要先关闭文档,然后再将其删除 - 在 NSFilePresenter 中检测到这一点accommodatePresentedItemDeletionWithCompletionHandler:

于 2012-05-13T06:50:59.173 回答