我已经更新了一个现有的 CoreData 应用程序以使用 CloudKit,以便它可以在多个设备之间保持数据同步(对于同一个 iCloud 帐户)。
有效!数据同步很好。
但主 UIViewController 的 View 不反射(reflect)新数据。要查看更改,我必须切换到不同的 View ,然后切换回主视图,该 View 在其 viewWillAppear()
函数中调用了 refreshData()
。然后它从数据存储中重新读取并显示所有数据(包括在其他设备上更新的任何数据)。
UIViewController 应该根据下面的 viewDidLoad()
观察 NSPersistentStoreRemoteChange
通知:
override func viewDidLoad() {
super.viewDidLoad()
// NotificationCenter.default.addObserver(self, selector: #selector(handleRemoteChange), name: .NSPersistentStoreRemoteChange, object: AppDelegate.appDelegate().persistentContainer.persistentStoreCoordinator)
NotificationCenter.default.addObserver(self, selector: #selector(handleRemoteChange), name: .NSPersistentStoreRemoteChange, object: nil)
}
但是处理函数永远不会被调用:
@objc func handleRemoteChange(notification: Notification) {
print("Handling remote change to data in Collection Controller")
refreshData()
}
那个 print 语句从不打印任何东西,那里设置的断点也从不触发。
我已将托管对象上下文配置为在创建 NSPersistentCloutKitContainer
后立即根据需要合并来自父对象的更改:
container.viewContext.automaticallyMergesChangesFromParent = true
该应用程序具有我在网上(和 Stack Overflow)搜索线索后了解到的所有相关 iCloud 功能和权利,包括:
- “远程通知”(后台模式)
- “CloudKit”(iCloud)
- 已创建并选择了一个容器,其标识符为 格式:iCloud.reverse.domain.app
容器的 persistentStoreDescription 将 NSPersistentStoreRemoteChangeNotificationPostOptionKey
选项设置为 true:
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
print("FAILED to load persistent store:\(storeDescription)\nERROR:\n\(error)\n\(error.userInfo)")
}
})
container.viewContext.automaticallyMergesChangesFromParent = true
for description in container.persistentStoreDescriptions {
description.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
}
很明显,数据正在同步。只是通知没有按预期工作。因此最终用户不会自动看到新的/同步的数据。
我怎样才能让它工作?
最佳答案
我有同样的问题,通过在调用 loadPersistentStores(completionHandler:) 之前配置自定义持久存储描述解决了
container = NSPersistentCloudKitContainer(name: "RubikClub")
// turn on persistent history tracking
let description = container.persistentStoreDescriptions.first
description?.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
description?.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
NotificationCenter.default.addObserver(self, selector: #selector(type(of: self).storeRemoteChange(_:)), name: .NSPersistentStoreRemoteChange, object: container.persistentStoreCoordinator)
container.loadPersistentStores { (_, error) in
if let error = error {
fatalError("init core data error: \(error.localizedDescription)")
}
}
container.viewContext.automaticallyMergesChangesFromParent = true
关于swift - CoreData 和 CloudKit Sync 有效,但 NSPersistentStoreRemoteChange 通知永远不会触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61790440/