Jerry Agin
Jerry Agin

Reputation: 719

NSMetaDataQuery does not complete

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

Answers (3)

Ogre Codes
Ogre Codes

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

marknote
marknote

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

marknote
marknote

Reputation: 1077

Change

    NSPredicate(format: "%K like '*'", NSMetadataItemFSNameKey)

to

    NSPredicate(format: "%K like '*.*'", NSMetadataItemFSNameKey)

Upvotes: 0

Related Questions