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:
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:
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:
(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.
Thanks for the tip regarding single quoting the time portion of NSPredicates, saved me a lot of headaches.
Cheers
Matt
A really great article! I’ve been struggling for the date bit in MDQueryRef, and now I’m using your tips. Thanks a lot!
Cool, glad to help. I really need to moderate my comments more than once a year.. :)