Для синхронизации необходимо не только поменять контейнер, но и правильно настроить контейнер. Конечно не забываем в Capabilities включить Remote notification. В CoreData в конфигурации включить поддержку iCloud.
Давайте по порядку:
-
Для правильной синхронизации с iCloud необходимо настроить историю отслеживания изменений, приёма и отправки уведомлений о изменении в контейнере
guard let description = container.persistentStoreDescriptions.first else {
fatalError("###\(#function): Failed to retrieve a persistent store description.")
}
description.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
description.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
-
Необходимо установить правильную политику синхронизации и объеденения новых данных
container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
container.viewContext.automaticallyMergesChangesFromParent = true
-
Для отслеживания окончания загрузки данных или каких-либо изменений в БД на другом устройстве (или другим пользователем, если контейрнер публичный), нужно добавить наблюдателя по нужному ключу
NotificationCenter.default.addObserver(self, selector: #selector(storeUpdate), name: .NSPersistentStoreRemoteChange, object: nil)
В методе селектора удобно подтягивать обновлённые данные из КорДаты try localContext.fetch(request)
и после обновлять все интерфейсы.
P.S. Для примера код инициализации контейнера в AppDelegate
lazy var persistentContainer: NSPersistentCloudKitContainer = {
let container = NSPersistentCloudKitContainer(name: "YourContainer")
guard let description = container.persistentStoreDescriptions.first else {
fatalError("###\(#function): Failed to retrieve a persistent store description.")
}
description.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
description.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
container.loadPersistentStores(completionHandler: { (_, error) in
if let error = error {
fatalError("###\(#function): Failed to load persistent stores:\(error)")
}
})
container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
container.viewContext.automaticallyMergesChangesFromParent = true
do {
try container.viewContext.setQueryGenerationFrom(.current)
} catch {
fatalError("###\(#function): Failed to pin viewContext to the current generation:\(error)")
}
NotificationCenter.default.addObserver(self, selector: #selector(storeUpdate), name: .NSPersistentStoreRemoteChange, object: nil)
return container
}()