使用NSMetadataQuery和NSPredicate返回目录列表 [英] Returning a list of directories with NSMetadataQuery and NSPredicate

查看:203
本文介绍了使用NSMetadataQuery和NSPredicate返回目录列表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试获取用户的iCloud文件夹中的目录列表。我找出了如何查找特殊类型的文件(如txt文件)并且工作正常:

I'm trying to get a list of directories in the user's iCloud folder. I worked out how to look for special types of files (such as txt files) and it works fine:

NSMetadataQuery *query = [[NSMetadataQuery alloc] init];
_query = query;

//Search all files in the Documents directories of the application’s iCloud container directories:
[query setSearchScopes:[NSArray arrayWithObject:NSMetadataQueryUbiquitousDocumentsScope]]; 

NSPredicate *pred = [NSPredicate predicateWithFormat:@"%K ENDSWITH '.txt'", NSMetadataItemFSNameKey];

[query setPredicate:pred];
[query startQuery];

但是,我现在只想获取目录。我已经阅读了有关 NSPredicate ,但我不知道如何寻找目录。我想NSPredicate不是为此而做的?我可以检查某个目录是否是这样的目录:

However, I'm now trying to get only directories. I've read through the docs concerning NSPredicate, but I have no clue how to go about looking for directories. I guess NSPredicate is not made for this? I can check if something is a directory like this:

    BOOL isDir;
BOOL exists = [fm fileExistsAtPath:path isDirectory:&isDir];
if (exists) {
    /* file exists */
    if (isDir) {
        /* file is a directory */
    }
 }

但如何将此应用于NSMetadataQuery,我不知道。我很感激能得到任何帮助。

But how to apply this to a NSMetadataQuery, I have no clue. I'd be grateful for any help I can get.

编辑:

我将谓词更改为 [NSPredicate predicateWithFormat:@%K.pathExtension ='',NSMetadataItemFSNameKey];

然后我确定查询的时间完成如下:

I then determine when the query is finished like so:

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(queryDidFinishGathering:) name:NSMetadataQueryDidFinishGatheringNotification object:query];
[query startQuery];

- (void)queryDidFinishGathering:(NSNotification *)notification {

NSMetadataQuery *query = [notification object];
[query disableUpdates]; // You should invoke this method before iterating over query results that could change due to live updates.
[query stopQuery]; // You would call this function to stop a query that is generating too many results to be useful but still want to access the available results.

[self loadData:query];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidFinishGatheringNotification object:query];
_query = nil; // we're done with it

}

最后,我做一个计数,但这总是给我0在云中我有多个目录(我通过Lion和Mobile Documents文件夹检查了这个;例如我有Documents / myTXTs等)。这很奇怪。如果我对文本文件进行计数,它会给我4,因为我有4个txt文件。所以我想我的目录没有被计算在内:

And finally, I do a count, but this will always give me 0 however many directories I have in the cloud (I checked this via Lion and the Mobile Documents folder; e.g. I have Documents/myTXTs etc.). This is very strange. If I do a count on the text files, it will give me 4 as I have 4 txt files. So I guess my directories are not being counted:

 - (void)loadData:(NSMetadataQuery *)query {

    NSLog(@"Query count %i", [query resultCount]);

...


推荐答案

我没有运气就尝试过EmptyStack的答案....

I've tried EmptyStack's answer without luck....

我发现 NSMetadataQuery 找不到目录,问题不在于 NSPredicate 是从结果中过滤目录,问题只是查询找不到文件夹。我已经尝试使用调试器,发现找到的所有 LBItem 都是常规文件而不是目录。我希望Apple将来能够改进这一点。
也许在MountainLion中这是更好的,因为它们似乎有文件夹支持... oops当然你没有在这里阅读,因为它仍然是NDA。算了吧

I've found that NSMetadataQuery does NOT find directories, The problem is not the NSPredicate is filtering directories from the results, the problem is simply the query don't find folders. I've tried with the debugger and found that all LBItems found, are of regular files not directories. I hope Apple improves this in the future. Maybe in MountainLion this is better since they seem to have folder support ... oops off course you didn't read this here because it's still NDA. Forget it

然而,至少有一种解决方法:

例如,如果您的文件结构是;

For example if your file structure is;

|_Folder
| |_file
| |_file2
|_Folder1
| |_file
|_file

我们使用谓词进行查询:

and we make a query with predicate:

predicateWithFormat:@"%K LIKE '*'", NSMetadataItemFSNameKey

结果将是(使用 NSMetadataItemURLKey 获取网址)

results will be (use NSMetadataItemURLKey to get the URL)

path/to/iCloud/Documents/Folder/file
path/to/iCloud/Documents/Folder/file2
path/to/iCloud/Documents/Folder1/file
path/to/iCloud/Documents/file

我们需要做的是过滤这些结果由我们自己查看每个URL的组件数量并根据需要切断URL。第一级的项目应该有 numberOfComponentsOfUbiquitousContainer + 1 ,下一级甚至还有一个,依此类推。
我们也需要丢弃重复(或者在本例中我们将获得文件夹两次)。

What we need to do is to filter these results by ourselves by looking at the number of components of each URL and chopping URLs as needed. Items at the first level should have numberOfComponentsOfUbiquitousContainer + 1, next level would have even one more and so on. We need to discard repetitions too (or like in this example we will get Folder twice).

可能不是最佳但对我有用,

Probably not optimal but works for me,

更好地使用下面的谓词,它会减少查询结果在抓取子文件夹时。

Better use below predicate, it reduce query results when crawling sub folders.

// dirPath is an NSString path of the directory you want
// to look at. Usually, for the top level directory:
// [NSFileManager URLForUbiquityContainerIdentifier:nil].path;
predicateWithFormat:@"%K BEGINSWITH %@", NSMetadataItemPathKey, dirPath];

这篇关于使用NSMetadataQuery和NSPredicate返回目录列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆