检测跨设备在iCloud中删除文档的正确方法?

时间:2012-05-02 01:48:32

标签: ios icloud uidocument

我找不到一种明显的方法来检测我正在监控的文档的删除(我缓存了我的应用所关注的文档列表)。

在Device1上: 当我删除文档时,我打电话给

        [fileCoordinator coordinateWritingItemAtURL:fileURL options:NSFileCoordinatorWritingForDeleting
          error:&err byAccessor:^(NSURL* writingURL) {
             [fileManager removeItemAtURL:writingURL error:nil];

这在Device1上工作正常,一切都保持同步。 在Device2上: 我试图依赖NSMetadataQuery通知:

NSMetadataQueryDidFinishGatheringNotification上的初始文件列表正常 文档添加/更改通过NSMetadataQueryDidUpdateNotification

正常进行

当我删除Device1上的文件时,我得到一个奇怪的结果:NSMetadataQueryDidUpdateNotification中有一个更新,其中列出了我的所有文档(除了已删除的文档) 我不确定我应该如何检测到丢失的文件已被删除或更新通知是否为此目的

问题1:我应该检查什么?

我尝试了另一条路线,即注册为iCloud网址的NSFilePresenter

- (NSURL *)iCloudDocumentsURL
{
    return [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil] URLByAppendingPathComponent:@"Documents"];
}

现在,当该URL中的文件发生变化时,我通过NSFilePresenter协议进行调用,但由于回调模糊,运行逻辑以确定丢失的文档的速度非常慢。 我回来的唯一电话是- (void)presentedItemDidChange; 我期待通过- (void)accommodatePresentedSubitemDeletionAtURL:(NSURL *)url completionHandler:(void (^)(NSError *errorOrNil))completionHandler收到回电 但这种方法从未被调用过。

问题2:知道如何让它工作吗?

3 个答案:

答案 0 :(得分:3)

由于您正在跟踪从iCloud报告的以前的文件,因此当前 iCloud列表中缺少已删除的文件,因此您只需将两个列表进行比较即可找到被删除的内容。

这就是我在“文件管理器”视图控制器中所做的事情,因为我保留了文件条目的NSMutableDictionary,其中包括主视图中文件“icons”位置的键。当我收到更新通知,并且该更新导致更多或更少的文件时,我会根据这些文件设置图标更改动画 变化。

答案 1 :(得分:2)

tobinjim是正确的,因为NSMetadataQuery每次都返回整个结果集。我曾预计只会发送更改以节省带宽,但我没有正确地进行RTFM。

一旦我弄明白,我遇到了iOS库中的一个错误。这是当我在一台设备上删除文档并且iCloud查询更新发现到我的其他设备时发生的崩溃:

    2012-06-25 13:15:12.343 app[19779:707] *** -[NSMutableIndexSet indexGreaterThanOrEqualToIndex:]: message sent to deallocated instance 0xdaae2c0
    (gdb) bt
    #0  0x31937870 in ___forwarding___ ()
    #1  0x31892650 in __forwarding_prep_0___ ()
    #2  0x373cc676 in __NSIndexSetEnumerate ()
    #3  0x373a1ee8 in -[NSIndexSet enumerateIndexesWithOptions:usingBlock:] ()
    #4  0x371c1f08 in -[LBQuery _processUpdates] ()
    #5  0x373571a6 in -[NSObject(NSThreadPerformAdditions) performSelector:onThread:withObject:waitUntilDone:modes:] ()
    #6  0x3737ffa4 in -[NSObject(NSThreadPerformAdditions) performSelector:onThread:withObject:waitUntilDone:] ()
    #7  0x371c2274 in -[LBQuery processUpdates] ()
    #8  0x373a88d6 in -[NSMetadataQuery _update] ()

我相信我找到了这个问题的原因。我正在审查Luke the Hiesterman的演示中的新IOS 6示例代码。我注意到没有像以前的iCloud示例应用程序那样调用NSMetadataQuery disable / enableUpdates。我删除了对这些的所有电话。我还改变了处理NSMetadataQueryDidUpdateNotification调用的方法,以异步方式运行,但是以排队方式运行。

NSMetadataQuery的线程之间似乎存在竞争条件。在一些调用中,查询的结果很好,但在其他时候,它们已经被释放,结果显示为NSZombie(感谢gdb比当前的lldb更好)。因此,跨线程启用和禁用查询会导致LBQuery通过调用已释放的对象而崩溃。

删除NSMetadataQuery的所有启用和禁用似乎加快了我的应用程序,iCloud似乎更加稳定。

答案 2 :(得分:1)

自iOS 8 NSMetadataQuery扩展NSMetadataQueryDidUpdateNotification userInfo NSMetadataQueryUpdateRemovedItemsKey后,您可以使用它来检测哪些文件已被删除。

https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSMetadataQuery_Class/#//apple_ref/doc/constant_group/Keys_for_Use_with_a_Notification_Info_Dictionary