Cocoa: Using NSPredicate and NSMetadataQuery

Apple, Cocoa, General

Hi Apple Cocoa developers. Here are some more tips and tricks for Cocoa development.

On Tiger, there is a new class called NSMetadataQuery that allows you to do some cool Spotlight searches. See the “Spotlighter” demo application included in /Developer/Examples/AppKit/Spotlighter.

Creating a predicate to get the search results that you want can be tricky, but alas, there is an easy way!

First, do a search inside of Finder that has the criteria you want. For example, below is a search for all images recently created:

Spotlightsearchexampleinfinder

Hit the save button and save it to your desktop. You can then show the info that Saved Search Query inside of Finder and see the Query it is using:

Searchqueryexample

You can also drag and drop it onto TextEdit to open up the file (it is just a simple XML plist). You can then extract the query via copy and paste:

(kMDItemContentTypeTree = ‘public.image’) && (kMDItemFSCreationDate >= $time.today(-7)) && (kMDItemContentType != com.apple.mail.emlx) && (kMDItemContentType != public.vcard)

So, you want to test this query be executing it from the command line. You should be able to do an “mdfind” and paste it after it, however, that won’t work! You must escape the $ with a slash since the shell interprets the slash as a file input.

You also have to quote the entire thing, as follows:

mdfind “(kMDItemContentTypeTree = 'public.image') &&
    (kMDItemFSCreationDate >= \$time.today(-7)) &&
    (kMDItemContentType != com.apple.mail.emlx) &&
    (kMDItemContentType != public.vcard)”

And, thus you can use it from a command prompt:

Commandpromptquerymdfind
(sorry for the ugly wrapping).

Okay — so, one would think they can paste this into a predicate and just use it as-is, right?

Well, no! The following would normally work:

[NSPredicate predicateWithFormat:@“kMDItemContentTypeTree = ‘public.image’ && (kMDItemFSCreationDate >= $time.today(-7)) && kMDItemContentType != ‘com.apple.mail.emlx’”] ;

But a small bug prevents it from actually parsing the text due to the $time reference (it might even crash!). You must single quote the $time part to get it to work:

[NSPredicate predicateWithFormat:@“kMDItemContentTypeTree = ‘public.image’ && (kMDItemFSCreationDate >= ‘$time.today(-7)’) && kMDItemContentType != ‘com.apple.mail.emlx’”] ;

Then, it should all be okay!

Have fun. Happy programming. Long live MacOS.

Previous in objc
no_thumbnail
Cocoa: Disappearing headers in CoreData generated TableViews
Next in objc
no_thumbnail
Cocoa: Creating a custom Color Picker in Cocoa. Part 1.

3
Leave a Reply

avatar
500
3 Comment threads
0 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
3 Comment authors
corbinJofell GallardoMatt Brook Recent comment authors
  Subscribe  
Notify of
Matt Brook
Guest
Matt Brook

Thanks for the tip regarding single quoting the time portion of NSPredicates, saved me a lot of headaches.
Cheers
Matt

Jofell Gallardo
Guest

A really great article! I’ve been struggling for the date bit in MDQueryRef, and now I’m using your tips. Thanks a lot!

(c) 2008-2019 Corbin Dunn

Privacy Policy

Subscribe to RSS feeds for entries.

98 queries. 0.286 seconds.

Log in