Returning a list of directories with NSMetadataQuery and NSPredicate

你。 提交于 2019-12-04 17:37:40

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

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

However there is at least one way of working-around this:

For example if your file structure is;

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

and we make a query with predicate:

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

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

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,

Update:

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];

If you want to get only the directories use the following predicate.

predicateWithFormat:@"%K.pathExtension = ''", NSMetadataItemFSNameKey

Note that, this doesn't guarantee that you will get only the directories by using this method as there are (I've seen some) files which has no extensions. But if you are sure that all your files has extensions then you can very well use this.

If you want to get all the files regardless of their extension, just add the NOT keyword to the above predicate,

predicateWithFormat:@"NOT %K.pathExtension = ''", NSMetadataItemFSNameKey

Try this:

[query setPredicate:[NSPredicate predicateWithFormat:@"%K like '*.txt'", NSMetadataItemFSNameKey]];

It works for me.

You can do this with MDQuery - which is the 'real' code that NSMetadataquery uses.

In Terminal, type 'mdls' then drag in a folder. Then type mdfind and use the provided example only change the kMDItemContentType type tree to public.folder - you will get lots of results.

Then to do this in code, you need to follow an MDQueryRef example. The code flow is identical to the Cocoa stuff, and I find the queries much easier to create and understand. You can set cocoa callbacks to the MDQuery - so its pretty well drop in compatible with NSMetadataquery.

NSMetadataQuery has some iCloud stuff that I don't think is in MDQuery. So they are not identical, I think.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!