Reputation: 719
I’m trying to explore the files available to my app in iCloud using NSMetaDataQuery
. I’m able to start the query, but it never finishes. Here’s my code.
func report1() {
let filemgr = FileManager.default
let url = filemgr.url(forUbiquityContainerIdentifier: nil)
guard url != nil else {
print("url is nil")
return
}
let metaDataQuery = NSMetadataQuery()
metaDataQuery.predicate =
NSPredicate(format: "%K like '*'", NSMetadataItemFSNameKey)
metaDataQuery.searchScopes = [NSMetadataQueryUbiquitousDocumentsScope]
NotificationCenter.default.addObserver(self,
selector: #selector(didFinish),
name: NSNotification.Name.NSMetadataQueryDidFinishGathering,
object: nil)
NotificationCenter.default.addObserver(self,
selector: #selector(didStart),
name: NSNotification.Name.NSMetadataQueryDidStartGathering,
object: nil)
NotificationCenter.default.addObserver(self,
selector: #selector(didUpdate),
name: NSNotification.Name.NSMetadataQueryDidUpdate,
object: nil)
let result = metaDataQuery.start()
print("metaDataQuery.start() returned \(result)")
}
@objc func didStart(notification: NSNotification) {
let query: NSMetadataQuery = notification.object as! NSMetadataQuery
print("didStart found \(query.results.count) items")
}
@objc func didFinish(notification: NSNotification) {
print("didFinish")
}
@objc func didUpdate(notification: NSNotification) {
print("didUpdate")
}
This prints the following:
didStart found 0 items
metaDataQuery.start() returned true
didStart
is getting called, but didFinish
and didUpdate
are never called. I get the same results if I substitute ==
or ==[cd]
for like
in the predicate. Changing NSMetadataQueryUbiquitousDocumentsScope
to NSMetadataQueryUbiquitousDataScope
has no effect. What am I missing?
The same issue seems to have been posed several times on this forum, but I'm not finding any satisfactory answers.
Upvotes: 5
Views: 1216
Reputation: 19621
For me, the problem was I wasn't calling query.start() from the main thread (I found the solution here.
For me the fix was as simple as:
DispatchQueue.main.async {
self.query.start()
}
Upvotes: 3
Reputation: 1077
I think I found what is the reason. Your code
let metaDataQuery = NSMetadataQuery()
This actually makes the metaDataQuery as local object, its lifecycle is in the function scope, and will be destroyed when the function ends. Then how can it work? Please make it as a member field.
Upvotes: 3
Reputation: 1077
Change
NSPredicate(format: "%K like '*'", NSMetadataItemFSNameKey)
to
NSPredicate(format: "%K like '*.*'", NSMetadataItemFSNameKey)
Upvotes: 0