Searching files - Objective-C
I am trying to search for a file. This returns 0 results. Does anyone know why?
NSMetadataQuery *q = [[NSMetadataQuery alloc] init];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"kMDItemFSNam开发者_如何学Ce == %@", @"test123456.png"];
[q setPredicate:predicate];
[q startQuery];
while ([q isGathering]) {
NSLog(@"%lu", [q resultCount]);
}
[q stopQuery];
update
NSMetadataQuery *q = [[NSMetadataQuery alloc] init];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"kMDItemFSName == %@", @"test123456.png"];
[q setPredicate:predicate];
[q startQuery];
NSLog(@"%lu", [q resultCount]);
[q stopQuery];
Thanks
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"kMDItemSFName == %@", @"test123456.png"];
If you copied that exactly from your code, methinks kMDItemSFName
should be kMDItemFSName
. ;-)
Are you using the foundation tool template, or a full application that will have a run loop?
Basically, I believe MDMetadataQuery
is designed to be run asynchronously, where you start the query and will be notified of the results when the query has finished.
From Introduction to Spotlight Query Programming Guide:
For applications that need to create queries and interact with the results there are two APIs available. The Spotlight metadata framework provides a low-level query API,
MDQuery
, that allows an application to search for files based on metadata values.MDQuery
is completely configurable, allowing you to run synchronous and asynchronous queries and provides fine-grain control of the frequency of results batching.The Cocoa frameworks's
NSMetadataQuery
class provides a high-level Objective-C interface to theMDQuery
API. This class allows you to construct queries using a subset of theNSPredicate
classes, and execute the queries asynchronously.NSMetadataQuery
supports Cocoa bindings, allowing you to display the results without writing any significant amount of glue code. As well,NSMetadataQuery
allows an application to specify the grouping of the results into multiple subcategories.NSMetadataQuery
does not support synchronous queries and provides minimal update notifications as data is collected.
See Technical Note TN2192 Querying Metadata With Spotlight.
Since NSMetadataQuery works asynchronously the run loop needs to reached to get results. You can set a delegate or register a notification that gets called when results are found or as soon as there are updates.
I don't find that mentioned in the Mac documentation but in the iOS 5 documentation they explicitly state that. Maybe it's not true for OS X? But you should give it a try.
"The query sends notifications as the results are returned in batches. The query sends the application a notification when the initial results gathering phase has completed." (found in http://developer.apple.com/library/mac/#documentation/Carbon/Conceptual/SpotlightQuery/Concepts/QueryingMetadata.html#//apple_ref/doc/uid/TP40001848-CJBEJBHH)
declare NSMetaDataQuery q in .h file and check resultCount on receiving NSMetadataQueryDidFinishGatheringNotification.
someFunction
{
[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(initalGatherComplete:)
name:NSMetadataQueryDidFinishGatheringNotification
object:metadataSearch];
q = [[NSMetadataQuery alloc] init];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"kMDItemFSName == %@", @"test123456.png"];
[q setPredicate:predicate];
[q startQuery];
}
- (void)initalGatherComplete:sender;
{
[q stopQuery];
NSLog(@"%lu",[q resultCount]);
[[NSNotificationCenter defaultCenter] removeObserver:self
name:NSMetadataQueryDidFinishGatheringNotification
object:metadataSearch];
}
精彩评论