简体   繁体   中英

CoreData + CloudKit only synching after minimizing and reopening app

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!

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM