[ad_1]
I want to obtain, and being notified, on recordsdata at iCloud Doc.
The record of filenames are identified up-front as we retailer the filenames in a iCloudKit (Not iCloud Doc)
The record of filenames will probably be up to date in the course of runtime. Then, as soon as the record of filenames is replace, we have to proceed to look and obtain for the recordsdata from iCloud Doc.
I want to make good use of NSMetadataQuery and take heed to record of notifications like NSMetadataQueryDidStartGathering.
The closest instance I can discover thus far is from https://medium.com/swlh/restore-your-applications-data-from-icloud-and-track-progress-a63a8bd3de38
The instance is exhibiting the way to deal with single file, with out useful resource cleanup (The observers usually are not eliminated)
I modified the instance to (additionally single file dealing with with out useful resource cleanup)
Imperfect instance as it will probably solely deal with single file, and never performing observers removing
class iCloudDocumentManager {
static let INSTANCE = iCloudDocumentManager()
var question: NSMetadataQuery!
non-public init() {
initialiseQuery()
addNotificationObservers()
question.operationQueue?.addOperation({ [weak self] in
self?.question.begin()
self?.question.enableUpdates()
})
}
non-public func initialiseQuery() {
question = NSMetadataQuery.init()
question.operationQueue = .primary
question.predicate = NSPredicate(format: "%Ok == %@", NSMetadataItemFSNameKey, "1ccd0ac7-b6c4-4804-9ee1-1031e57c4ec7.jpeg")
question.searchScopes = [
NSMetadataQueryUbiquitousDocumentsScope
]
}
non-public func addNotificationObservers() {
NotificationCenter.default.addObserver(forName: NSNotification.Title.NSMetadataQueryDidStartGathering, object: question, queue: question.operationQueue) { (notification) in
print(">>>> NSMetadataQueryDidStartGathering")
self.processCloudFiles()
}
NotificationCenter.default.addObserver(forName: NSNotification.Title.NSMetadataQueryGatheringProgress, object: question, queue: question.operationQueue) { (notification) in
print(">>>> NSMetadataQueryGatheringProgress")
self.processCloudFiles()
}
NotificationCenter.default.addObserver(forName: NSNotification.Title.NSMetadataQueryDidUpdate, object: question, queue: question.operationQueue) { (notification) in
print(">>>> NSMetadataQueryDidUpdate")
self.processCloudFiles()
}
}
@objc func processCloudFiles() {
if question.outcomes.rely == 0 { return }
for merchandise in question.outcomes {
guard let merchandise = merchandise as? NSMetadataItem else { proceed }
guard let fileItemURL = merchandise.worth(forAttribute: NSMetadataItemURLKey) as? URL else { proceed }
strive? FileManager.default.startDownloadingUbiquitousItem(at: fileItemURL)
if let fileDownloaded = merchandise.worth(forAttribute: NSMetadataUbiquitousItemDownloadingStatusKey) as? String, fileDownloaded == NSMetadataUbiquitousItemDownloadingStatusCurrent {
question.disableUpdates()
question.operationQueue?.addOperation({ [weak self] in
self?.question.cease()
})
print(">>>> Obtain full (fileItemURL)")
} else if let error = merchandise.worth(forAttribute: NSMetadataUbiquitousItemDownloadingErrorKey) as? NSError {
print(error.localizedDescription)
} else {
if let keyProgress = merchandise.worth(forAttribute: NSMetadataUbiquitousItemPercentDownloadedKey) as? Double {
print(">>>> File downloaded p.c (fileItemURL) ---", keyProgress)
}
}
}
}
}
My questions are
- When, and the way I ought to take away the observers? After the obtain is accomplished? What if the obtain is failed? How I will probably be notified so that there’s a likelihood for me to take away the observers?
- How I ought to deal with a considerable amount of recordsdata say like 10,000 recordsdata? Does that imply I have to have 10,000 of NSMetadataQuery and three * 10,000 of observers? What’s a scalable strategy to obtain so?
processCloudFileswill probably be working in primary thread which could trigger UI unresponsive. How can I run such operations in background thread?
Thanks.
[ad_2]
