Thursday, October 15, 2026
HomeiOS Developmentios - Easy methods to obtain and being notified, a listing of...

ios – Easy methods to obtain and being notified, a listing of recordsdata in iCloud Doc, in a scalable manner?

[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

  1. 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?
  2. 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?
  3. processCloudFiles will probably be working in primary thread which could trigger UI unresponsive. How can I run such operations in background thread?

Thanks.

[ad_2]

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments