iCloud - 在另一台设备上重命名打开的文档有时会失败
Posted
技术标签:
【中文标题】iCloud - 在另一台设备上重命名打开的文档有时会失败【英文标题】:iCloud - renaming open documents on another device sometimes fails 【发布时间】:2011-12-28 13:25:18 【问题描述】:问题:我正在设备 A 上处理 iCloud 文档,例如iPod 触摸。然后我更改设备 B 上的文档名称,例如我的 Mac(通过 Finder)。更改会上传到云端,并在设备 A 暂停后听到。
然后:
有时一切都很好 - 我通过更改的fileURL
属性获取名称更改,并可以相应地更新我的界面 - 文档继续按应有的方式运行
有时,文档的 fileURL 会以如下形式返回:file://localhost/var/mobile/Library/Mobile%20Documents/.ubd/peer-43A0AEB6-84CE-283E-CA39-FCC4EF3BC8F8-v23/ftr/purg-012fdcfbe3b3bbce6e603fdfd2f000b2cb28649e95
毫不奇怪,此文件不会保存。
谁能解释发生了什么以及如何解决它?
背景
名称更改由NSMetadataQuery
接收。因此,例如,我可以重命名未打开的文档,并且我的所有 iCloud 功能都可以正常工作。该问题似乎只发生在打开的文档中。
其他 iCloud 功能运行良好,例如我可以在一台设备上更改内容,例如我的 Mac,然后在另一台设备上检测并更新我的界面,例如我的 iPod Touch,打开了相关的 iCloud 文档。
当我为我的 UIDocument 子类添加 presentedItemDidMoveToURL:
的覆盖时,我第一次发现了这一点。覆盖可靠地获取在云中进行的名称更改,例如在另一台设备上重命名文档。然后 sometimes 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
之后 sometimes 将返回新名称并且 有时它会返回“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: 调用,此外,相关对象可以侦听其他设备上的删除通知。
【问题讨论】:
我尝试仅使用 DocumentState 使 iCloud 工作大约一个月——这是我缺少的部分。在添加此代码之前,项目有时会在删除后返回,或者我会得到不断变化的文档状态的连续流 【参考方案1】:当在本地打开 UIDocument 并从远程设备中删除时,会出现这种类型的 URL:
file://localhost/var/mobile/Library/Mobile%20Documents/.ubd/peer-43A0AEB6-84CE-283E-CA39-FCC4EF3BC8F8-v23/ftr/purg-
您需要先关闭文档,然后才能将其删除 - 在 NSFilePresenter 的 accommodatePresentedItemDeletionWithCompletionHandler:
中检测到这一点
【讨论】:
以上是关于iCloud - 在另一台设备上重命名打开的文档有时会失败的主要内容,如果未能解决你的问题,请参考以下文章