vendredi 10 juin 2016

On iOS 8 Simulator NSMetadataQuery always return value = 0


I'm adding support for iCloud to my App, but unfortunately I have a problem. What I try to do is to start a file search on iCloud through NSMetadataQuery for finding existing file and then process them later. This is my simplified class:

import UIKit    

class AViCloudDriveManager: NSObject {

    var metaDataQuery: NSMetadataQuery?

    // Check if iCloud is available
    func isiCloudAvailable() -> Bool {
        if NSFileManager.defaultManager().ubiquityIdentityToken != nil {
            return true
        }
        else {
            return false
        }
    }

    // Start to search for existing file on iCloud
    func findAndDownloadAllBackup () {
        // Start NSMetadataQuery
        self.createQuery()
    }

    // I make sure that NSMetadataQuery start on MainThread
    func createQuery() {
        if (NSThread.isMainThread()) {
            self.createMetadataQuery()
        } else {
            NSOperationQueue.mainQueue().addOperationWithBlock {
                self.createMetadataQuery()
            }

        }
    }

    // Create and start metaDataQuery
    func createMetadataQuery() {

        if isiCloudAvailable() && AVReachability.isConnectedToNetworkWithRequest() {

            metaDataQuery = NSMetadataQuery()
            metaDataQuery!.searchScopes = [NSMetadataQueryUbiquitousDocumentsScope, NSMetadataQueryUbiquitousDataScope]
            metaDataQuery!.predicate = NSPredicate.init(format: "%K LIKE '*'", argumentArray: [NSMetadataItemFSNameKey])

            let notificationCenter: NSNotificationCenter = NSNotificationCenter.defaultCenter()

            notificationCenter.addObserverForName(NSMetadataQueryDidFinishGatheringNotification, object:metaDataQuery!, queue:NSOperationQueue(), usingBlock: { notification in
                // disable query while processing file
                self.metaDataQuery!.disableUpdates()
                // process the results
                self.fileListReceived()
                // enable query after processing file
                self.metaDataQuery!.enableUpdates()
            })

            notificationCenter.addObserverForName(NSMetadataQueryDidUpdateNotification, object:metaDataQuery!, queue:NSOperationQueue(), usingBlock: { notification in
                // disable query while processing file
                self.metaDataQuery!.disableUpdates()
                // process the results
                self.fileListReceived()
                // enable query after processing file
                self.metaDataQuery!.enableUpdates()
            })
        } else {
            // No connection or iCloud not available
        }
    }

    // I make sure that file processing is done async
    func fileListReceived() {
        if (NSThread.isMainThread())
        {
            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
                self.processFiles()
            })
        } else {
            processFiles()
        }
    }

    // process the results
    func processFiles() {

        let queue = dispatch_queue_create("av.com.andreavenanzi.queue", DISPATCH_QUEUE_SERIAL)

        dispatch_sync(queue) {
            if let queryResults = self.metaDataQuery?.results {
                /* -- On iOS 8 queryResults is always with values = 0 -- */
                for result in queryResults {
                    // Process result
                }
            }
            // Do other stuff
            // If there are file in download or in upload keep the query alive
            // otherwise disableUpdates, stop the query and remove from notificationCenter
        }
    }
}

And to start the query I use:

let iCloudDriveManager = AViCloudDriveManager()
iCloudDriveManager.findAndDownloadAllBackup()

Everything works fine when I run the App on the iOS 9 simulator (here works but it doesn't upload on iCloud) or on an iPhone and an iPad both with iOS 9. Instead if I test on iOS 8 simulator, the NSMetadataQuery always returns an empty array. Unfortunately I don't have any access to devices with iOS 8 on which to test everything, so I ask you if it's a bug in Xcode (my version is 7.3.1 with OS X 10.11.5) or there is something wrong in my code? Thanks so much!


Aucun commentaire:

Enregistrer un commentaire