4

I am seeing .NSPersistentStoreRemoteChange notifications being received multiple times, sometimes up to 10 times.

I don't think this is harmful, but best case it's using up processing power.

So my questions are:

  • Is this harmful?
  • Can I prevent it?
  • If not, is there a recommended way to ignore duplicate notifications?

--

I have the following code to setup my container. This is contained in the initialiser of a singleton and I have confirmed that it is called once.

guard let modelURL = Bundle(for: type(of: self)).url(forResource: momdName, withExtension:"momd"),
            let mom = NSManagedObjectModel(contentsOf: modelURL)
            else {
                fatalError(" Error loading model from bundle")
        }
        
        let containerURL = folderToStoreDatabaseIn.appendingPathComponent("Model.sqlite")
      
            container = NSPersistentCloudKitContainer(name: momdName, managedObjectModel: mom)
            
            guard let description = container.persistentStoreDescriptions.first else {
                fatalError(" ###\(#function): Failed to retrieve a persistent store description.")
            }
            
            description.url = containerURL
            description.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
            description.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
              
        super.init()
        
            // this must be called after super.init()
            // ***** ADD OBSERVER *****
            NotificationCenter.default.addObserver(self,
                                                   selector: #selector(updatedFromCKCD(_:)),
                                                   name: .NSPersistentStoreRemoteChange,
                                                   object: container.persistentStoreCoordinator)
        
        if let tokenData = try? Data(contentsOf: tokenFile) {
            do {
                lastToken = try NSKeyedUnarchiver.unarchivedObject(ofClass: NSPersistentHistoryToken.self, from: tokenData)
            } catch {
                Logger.error(" ###\(#function): Failed to unarchive NSPersistentHistoryToken. Error = \(error)")
            }
        }

The code to process these changes:

// https://developer.apple.com/documentation/coredata/consuming_relevant_store_changes
    @objc func updatedFromCKCD(_ notifiction: Notification) {
        let fetchHistoryRequest = NSPersistentHistoryChangeRequest.fetchHistory(
            after: lastToken
        )
        
        let context = container.newBackgroundContext()
        guard
            let historyResult = try? context.execute(fetchHistoryRequest)
                as? NSPersistentHistoryResult,
            let history = historyResult.result as? [NSPersistentHistoryTransaction]
            else {
                Logger.error("⛈ Could not convert history result to transactions")
                assertionFailure()
                return
        }
        Logger.debug("⛈ Found cloud changes since: \(self.lastToken?.description ?? "nil")")
        
        DispatchQueue.main.async {
        // look for particular set of changes which require the user to take action
        ...
        }
    }
lewis
  • 2,936
  • 2
  • 37
  • 72
  • to ask the obvious....you're sure there is only one change happening in CloudKit? or is the issue there are multiple changes happening and you are expecting to get a single notification? – Steve B Sep 03 '20 at 12:05
  • @SteveB Pretty sure. I launch the app attached to the debugger with the app not open on other devices and I see a bunch of notifications – lewis Jan 12 '21 at 18:03

0 Answers0