我很难理解NSMetadataQuery的更新是如何工作的。
我正在尝试确定某个文件是否已完成从iCloud的下载。我最初的查询很清楚地告诉我,文件没有下载,我可以开始下载,但如果下载文件需要花费任何时间,我想设置一个进度条。我调用了enableUpdates,但它似乎并没有改变下载/下载状态或下载百分比,尽管我相当确定文件正在下载中。(我陷入了while循环。如果我退出并重新运行应用程序,它会看到下载的文件,并跳过while循环。)
是否必须启动新查询才能获取更新?如果是,enableUpdates和disableUpdates的功能是什么?
是否有一些不同的方式必须调用初始查询才能获得更新?我从文档中得到了这种印象,但我找不到任何细节来解释这一点。
发布于 2013-05-04 11:01:11
我设法解决了这个问题,但这是一个经典的案例,尝试了这么多不同的东西,遇到了如此多的砖墙,以至于我不再记得我到底做了什么才解决了这个问题,更不用说为什么我一开始就有这个问题了。也许我可以分享一些我遇到的事情。
一个是http://blog.wadetregaskis.com/icloud-documentation-is-crap/上的博客。这一段解释了NSMetadatQuery的实际工作原理:
这解释了NSMetadataQuery的一些至关重要的东西:长话短说,
NSMetadataQueryDidUpdateNotification不会做你可能期望的事情。当然不是我所期望的。我读到文档说它将用于交付结果,NSMetadataQueryDidFinishGatheringNotification将在完整的第一遍完成后发布。这是苹果其他API中使用的一个非常典型的模式(包括Spotlight,所以人们会认为NSMetadataQuery也是一样的)。但事实并非如此。
相反,所有第一次完整运行的结果都被缓冲起来,并由NSMetadataQueryDidFinishGatheringNotification提供。NSMetadataQueryDidUpdateNotification纯粹用于后续的实时更改。
另一件我认为可能给我带来问题的事情是,我可能同时有多个NSMetadataQuery实例处于活动状态。我不确定,也不知道为什么这会阻止他们中的任何一个发送更新通知。
无论如何,下面的代码现在可以为我工作了:
if (usingIcloud) {
if (query) [query disableUpdates];
query.predicate = [NSPredicate predicateWithFormat:@"%K like '*.caf' or %K like '*.mov'", NSMetadataItemFSNameKey, NSMetadataItemFSNameKey];
query.searchScopes = [NSArray arrayWithObject:NSMetadataQueryUbiquitousDocumentsScope];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(updateUbiquitousDocuments:)
name:NSMetadataQueryDidFinishGatheringNotification
object:nil];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(updateUbiquitousProgress:)
name:NSMetadataQueryDidUpdateNotification
object:nil];
[query enableUpdates];
}我能够得到更新,告诉我在我的updateUbiquitousProgress方法中已经下载了多少给定的文件,并让它运行一个进度条。如果任何人想了解更多或看到更多最终工作的代码,我很乐意为您效劳。
发布于 2013-05-02 11:04:39
Apple在这里提供了非常好的示例代码和解释:
基本上,您只是让查询一直运行(除非您进入后台)。每当情况发生变化时,您都会收到通知,并相应地维护您的文档列表。尚未从云中下载的文档最初是一个占位符;正如您在下一节“从iCloud下载文档文件”中看到的那样,只有在您要求使用startDownloadingUbiquitousItemAtURL:error: (或尝试使用openWithCompletionHander:读取文档)时,才会进行下载。
https://stackoverflow.com/questions/16328363
复制相似问题