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