iCloud NSMetadata查询结果为空

时间:2013-01-01 21:02:16

标签: objective-c ios nsarray icloud

我一直在努力将添加到我的项目中(这在包子中非常痛苦)并且我能够保存和删除文件,但我无法获取文件列表存储在iCloud中。我尝试过大约10个不同网站的解决方案(包括Apple文档)。每当我调用[self.query startQuery];时,一切似乎都在起作用:调用正确的方法,方法完全按照应有的方式执行。然后,当我在我的应用程序的iCloud Documents目录中请求个文件时,我得到两个括号,它们之间没有任何内容(当我在NSLog中查看时):File List: ( )。我知道在我的应用程序的iCloud Documents目录中有各种形状,扩展名,大小和名称的许多不同文档,因为我一直在使用iCloud Developer站点来检查是否有效。我设置查询的第一种方法如下:

- (void)syncWithCloud {
self.query = [[NSMetadataQuery alloc] init];
NSURL *mobileDocumentsDirectoryURL = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
[query setSearchScopes:[NSArray arrayWithObjects:NSMetadataQueryUbiquitousDocumentsScope, nil]];
//[query setPredicate:[NSPredicate predicateWithFormat:@"%K LIKE '*'", NSMetadataItemFSNameKey]];
[query setPredicate:[NSPredicate predicateWithFormat:[NSString stringWithFormat:@"%%K like \"%@*\"", [mobileDocumentsDirectoryURL path]], NSMetadataItemPathKey]];

//Pull a list of all the Documents in The Cloud
[[NSNotificationCenter defaultCenter] addObserver:self  selector:@selector(processFiles:)
                                             name:NSMetadataQueryDidFinishGatheringNotification object:self.query];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(processFiles:)
                                             name:NSMetadataQueryDidUpdateNotification object:self.query];

[self.query startQuery];
}

Apple提供的process files method是下一个:

- (void)processFiles:(NSNotification*)aNotification {
    NSMutableArray *discoveredFiles = [NSMutableArray array];

    //Always disable updates while processing results.
    [query disableUpdates];

    //The query reports all files found, every time.
    NSArray *queryResults = [query results];
    for (NSMetadataItem *result in queryResults) {
        NSURL *fileURL = [result valueForAttribute:NSMetadataItemURLKey];
        NSNumber *aBool = nil;

        // Don't include hidden files.
        [fileURL getResourceValue:&aBool forKey:NSURLIsHiddenKey error:nil];
        if (aBool && ![aBool boolValue])
            [discoveredFiles addObject:fileURL];
    }

    //Update the list of documents.
    [FileList removeAllObjects];
    [FileList addObjectsFromArray:discoveredFiles];
    //[self.tableView reloadData];

    //Reenable query updates.
    [query enableUpdates];

    NSLog(@"File List: %@", FileList);
}

为什么这不能给我一个文件列表或至少某种数据?我是否定义了NSMetadata查询错误,也许我的谓词格式不正确?我知道我做错了,因为iCloud无法复杂化(或者可能吗?) 感谢您的帮助!

编辑#1:我将继续尝试不同的方法解决此问题。使用下面的答案之一,我更改了谓词过滤器,如下所示:

[query setPredicate:[NSPredicate predicateWithFormat:@"NSMetadataItemFSNameKey LIKE '*'"]];

我还在[query enableUpdates]电话之前添加了以下行:

for (NSMetadataItem *item in query.results) {
        [FileList addObject:[item valueForAttribute:NSMetadataItemFSNameKey]];
 }

processFiles方法中,我尝试将所有代码放在后台线程上,但这没有区别 - 事实上,当代码没有在后台线程上执行时{{ 1}}给我这个FileList而不是(null)

我的问题可能与线程管理或内存分配有关吗?请注意我使用的是ARC。

修改#2:( )变量是我FileList中定义的NSMutableArray,并在调用@interface之前在-(id)init方法中初始化方法

编辑#3:在使用断点测试我的代码时,我发现以下永远不会运行 - 甚至一次。这让我相信:
  A.正确的目录未与
连接   B. iCloud无法查看目录中的文件   C.我的NSMetadataQuery没有正确设置   D.完全不同的东西

这是启动永远不会运行的for循环的代码:

processFiles

2 个答案:

答案 0 :(得分:1)

由于您已经将搜索范围设置为正确,因此不需要在谓词中使用特殊过滤器。 只需使用:

query.predicate = [NSPredicate predicateWithFormat:@"NSMetadataItemFSNameKey == '*'"];

要使用数组:

NSMutableArray *array = [NSMutableArray array];
for (NSMetadataItem *item in query.results) {
        [array addObject:[item valueForAttribute:NSMetadataItemFSNameKey]];
}

答案 1 :(得分:0)

我已经解决了我的问题。获取iCloud中的文件列表只需要正确定义,分配和初始化属性。 SAE 的回答和SO posting帮助我解决了我的问题并创建了名为iCloud Document Sync的GitHub回购。 iCloud Document Sync类将整个iCloud Document存储过程简化为几行代码。提交链接here修复了我的问题。