NSMetaDataQuery never calls back with NSMetadataQu

2019-01-26 13:11发布

For an iCloud plugin I'm writing, I subscribe my iCloud manager class to these iCloud NSMetaDataQuery observers:

// Add a predicate for finding the documents
NSString* filePattern = [NSString stringWithFormat:@"*.%@", @"*"];

self.metadataQuery = [[NSMetadataQuery alloc] init];

// Before starting to query, it is required to set the search scope.
arrayWithObject:NSMetadataQueryUbiquitousDocumentsScope]];

// It is also required to set a search predicate.
[self.metadataQuery setPredicate:[NSPredicate predicateWithFormat:@"%K LIKE %@", NSMetadataItemFSNameKey, filePattern]];

// Listen for the second phase live-updating
[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(queryDidReceiveNotification:) name:NSMetadataQueryDidUpdateNotification object:nil];

// Listen for the first phase gathering
[[NSNotificationCenter defaultCenter] addObserver:self
                                      selector:@selector(queryIsDoneGathering:) name:NSMetadataQueryDidFinishGatheringNotification
                                           object:nil];

[self.metadataQuery startQuery];

The problem is that none of these selectors are actually ever called back, not even once, and I especially need the NSMetaDataQueryDidUpdateNotification to track upload/download progress of files in the cloud.

An odd thing is that I had this working the other day, but somehow it just stopped working and I've starred myself blind in trying to figure out what the problem actually is. By subscriping to the NSMetadataQueryDidStartGatheringNotification I can see that it does start, but it's like it never finishes. It is quite weird.

I was wondering if anyone have any clue at all as what to be wrong with the above code? Or where else I can look for the problem.

Thank you for your time :)

2条回答
家丑人穷心不美
2楼-- · 2019-01-26 13:27

Make sure you start the NSMetadataQuery in the main thread. Back then this requirement was not documented.

查看更多
走好不送
3楼-- · 2019-01-26 13:33

This was quite the secret to dig up. I don't know if you've given up by now, but at long last, I might be able to help.

It turns out that for some (all?) C++ app configurations, there is a message pump that doesn't run automatically. In my app, I finally started getting my expected callbacks after placing a loop like this following my [m_query startQuery] call:
// make it look syncronous for now while( m_state != finished ) { Check_For_Interruption(); [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:timeslice]]; //<--**this line is the key** }
where the callbacks are setup to correctly update the m_state variable.

My example just blocks, using it's own thread timeslice to run the loop (unless interrupted by a timeout being reached), but this could also be set up in an asynchronous way.

Another thing to note for those who go overboard on legacy support:
This method did cause the app to start leaking mach ports on OS X 10.9 and older. Haven't seen any problems on anything newer than that, though.

查看更多
登录 后发表回答