Reputation: 8120
I am currently making an app that needs it's CoreData storage to be synced via iCloud across devices.
Everything works fine except that it's not synching in real-time. (Or at least somewhat close to that). It's not syncing at all when I am doing nothing on Device2 after Device1 changed something. In fact, I have to minimize and reopen the app on Device2 to get the synching working.
This demonstrates it very well: (source)
Here would be a snippet of my code:
let container: NSPersistentCloudKitContainer
var context: NSManagedObjectContext { container.viewContext }
init() {
container = NSPersistentCloudKitContainer(name: "__Decision")
guard let description = container.persistentStoreDescriptions.first else { ... }
description.setOption(true as NSObject, forKey:
NSPersistentStoreRemoteChangeNotificationPostOptionKey)
container.loadPersistentStores(completionHandler: { ... })
container.viewContext.automaticallyMergesChangesFromParent = true
container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
NotificationCenter.default.addObserver(self, selector: #selector(self.processUpdate), name: .NSPersistentStoreRemoteChange, object: nil)
}
@objc func processUpdate(notification: NSNotification) {
operationQueue.addOperation {
DispatchQueue.main.async { ... } //Fetch new synched data and update UI
}
}
lazy var operationQueue: OperationQueue = {
var queue = OperationQueue()
queue.maxConcurrentOperationCount = 1
return queue
}()
I have followed the documentation by apple and other tutorials, since this is my first project with CloudKit + CoreData.
Everything seems identical to what they have done.. I have no idea and been working on this problem since days.
Thank you!
Upvotes: 6
Views: 1170
Reputation: 8517
I just show you my setup, because I had the same issue once. I am using CloudKit aswell for macOS and iOS syncing and it does work now. The view gets updated with using SwiftUI.
In my AppDelegate I first register for remoteNotification
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
application.registerForRemoteNotifications()
return true
}
My persistenContainer does look like yours:
lazy var persistentContainer: NSPersistentCloudKitContainer = {
let container = NSPersistentCloudKitContainer(name: "name")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
container.viewContext.automaticallyMergesChangesFromParent = true
container.viewContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy
return container
}()
And then my signing tab, add background modes:
.. and add Push and iCloud
Also, be patient. Sometimes syncing does need several minutes to get updated.
Upvotes: 8