Trying to run the following code:
#import <Foundation/Foundation.h>
@interface FileQuery : NSObject
@end
@interface FileQuery()
@property (nonatomic, strong) NSMetadataQuery *query;
@property (nonatomic, strong) NSMutableArray<NSURL *> *fileArray;
@end
@implementation FileQuery
-(void)stopQuery {
if (_query) {
NSLog(@"No longer watching iCloud dir...");
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidFinishGatheringNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidUpdateNotification object:nil];
[_query stopQuery];
_query = nil;
_fileArray = nil;
}
}
-(BOOL)startQuery:(NSString *)suffix {
[_query stopQuery];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(processFiles:)
name:NSMetadataQueryDidFinishGatheringNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(processFiles:)
name:NSMetadataQueryDidUpdateNotification
object:nil];
_query = [NSMetadataQuery new];
if (_query) {
NSLog(@"aa");
_fileArray = [NSMutableArray new];
[_query setSearchScopes:@[NSMetadataQueryLocalComputerScope]];
[_query setPredicate:[NSPredicate predicateWithFormat:@"%K BEGINSWITH %@",
NSMetadataItemFSNameKey, suffix]];
dispatch_async(dispatch_get_main_queue(), ^{
if ([_query startQuery]) {
[_query enableUpdates];
NSLog(@"Finished with query = %@, predicate = %@", _query, _query.predicate);
}
});
}
});
NSLog(@"bb");
return TRUE;
}
- (void)processFiles:(NSNotification *)notification {
[_query disableUpdates];
// The query reports all files found, every time.
NSArray * queryResults = [_query results];
NSLog(@"Results = %@", queryResults);
for (NSMetadataItem * result in queryResults) {
NSURL * fileURL = [result valueForAttribute:NSMetadataItemURLKey];
NSLog(@"file = %@", fileURL);
[_fileArray addObject:fileURL];
}
[self stopQuery];
}
@end
int main(int argc, char *argv[]) {
if (argc != 2) {
NSLog(@"Error in number of params");
return 0;
}
NSString *s = [NSString stringWithFormat:@"%s", argv[1]];
NSLog(@"suffix = %@", s);
FileQuery *q = [FileQuery new];
if ([q startQuery:s]) {
while(true) {
NSLog(@"1");
sleep(100);
}
} else {
NSLog(@"query failed");
}
return 0;
}
For some reason, the NSMetadataQueryDidFinishGatheringNotification is never called.
Also, the NSMetadataQueryDidUpdateNotification notification is also never called.
Anyone has any idea as to why? Does anyone has any better idea for Spotlight search of files?
Thank you very much!
Your code works on my machine, when I make one modification. Instead of calling
sleep
in a loop, callCFRunLoopRun()
:The notification mechanism is implemented using the run loop, so you have to have one running for it to do its magic.