CoreData not updated until application inactivates
Asked Answered
B

2

5

I'm building a Macos CoreData+CloudKit app.

I first create my container by doing this:

let container = NSPersistentCloudKitContainer(name: "TestApp")
let description = container.persistentStoreDescriptions.first
description?.setOption(true as NSNumber,
                       forKey: NSPersistentHistoryTrackingKey)
let remoteChangeKey = "NSPersistentStoreRemoteChangeNotificationOptionKey"
description?.setOption(true as NSNumber,
                           forKey: remoteChangeKey)
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
    if let error = error {
        fatalError("Unresolved error \(error)")
    }
})

I'm registering to receive remote changes by doing this:

NotificationCenter.default.addObserver(
            self,
            selector: #selector(fetchChanges),
            name: NSNotification.Name(
                rawValue: "NSPersistentStoreRemoteChangeNotification"),
            object: persistentContainer.persistentStoreCoordinator
        )

And in fetchChanges, I just reload my UI by

  1. Fetching the data
  2. Reloading my tableView

However, I found out that fetchChanges is never called until the application inactivates. I see this in the log as:

CoreData: debug: CoreData+CloudKit: -[PFCloudKitThrottledNotificationObserver noteRecievedNotification:](40): <PFCloudKitThrottledNotificationObserver: 0x600003fb3fc0>: Got: NSApplicationWillBecomeActiveNotification - 0

What I'm assuming is happening is when CoreData detects my window inactivates via the NSApplicationWillBecomeActiveNotification event, it spawns a background task to fetch the remote iCloud data into the local store.

At that point, the NSPersistantStoreRemoteChangeNotification is received.

My question is how do you force the local store to sync with iCloud?

Any help is greatly appreciated.

Balthasar answered 8/2, 2021 at 4:37 Comment(0)
O
0

Some possible clues:

  1. You need to activate "Background fetch" in the "Background Modes" of the target's Signing & Capabilities
  2. This happened to me because I needed to sign in to iCloud again (I had a prompt in the Settings, but if you don't it's worth trying to sign out and sign back in)
Oligosaccharide answered 24/4, 2022 at 19:45 Comment(0)
C
0

I'm facing the same issue. The app doesn't sync until I deactivate and activate the app again. Therefore, your assumption is correct that it depends on willBecomeActiveNotification.

To force the synchronization you can run:

NotificationCenter.default.post(.init(name: NSApplication.willBecomeActiveNotification))

or schedule some Timer with it.

Of course, this solution is not perfect and it's actually a workaround. However, I spent many hours trying to figure out what's going on and I don't see any other solution at the moment.

Copenhagen answered 28/7 at 21:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.