CoreData 和 CloudKit 同步有效,但 NSPersistentStoreRemoteChange 通知永远不会触发
CoreData and CloudKit Sync works, but NSPersistentStoreRemoteChange notification never fires
我已经更新了现有的 CoreData 应用程序以使用 CloudKit 以便它可以在多个设备之间保持数据同步(对于同一个 iCloud 帐户)。
有效!数据同步正常。
但是主 UIViewController 的视图没有反映新数据。要查看更改,我必须切换到不同的视图,然后切换回在其 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)
}
很明显,数据正在同步。只是通知没有按预期工作。所以最终用户不会自动看到 new/sync 的数据。
我怎样才能让它工作?
我也遇到了同样的问题。我刚刚发现它在 TestFlight 构建中工作正常,但是当直接使用 Xcode 构建时,它却没有。你试过了吗?
还请记得听取此处概述的远程更改:
https://developer.apple.com/documentation/coredata/consuming_relevant_store_changes
这似乎需要 NotificationCenter.default.addObserver
object:
字段为 container.persistentStoreCoordinator
才能工作,这在 https://developer.apple.com/documentation/coredata/consuming_relevant_store_changes.
的文档中
Apple 在 https://developer.apple.com/documentation/coredata/synchronizing_a_local_store_to_the_cloud 的示例代码使用 object: container
但不起作用。
听众:
NotificationCenter.default.addObserver(self, selector: #selector(handleRemoteChange), name: .NSPersistentStoreRemoteChange, object: nil)
应该加在里面
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Here:
NotificationCenter.default.addObserver(self, selector: #selector(handleRemoteChange), name: .NSPersistentStoreRemoteChange, object: nil)
}
不要忘记取消订阅视图将消失:
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
NotificationCenter.default.removeObserver(self, name: .NSPersistentStoreRemoteChange, object: nil)
}
我有同样的问题,通过 在调用 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
我已经更新了现有的 CoreData 应用程序以使用 CloudKit 以便它可以在多个设备之间保持数据同步(对于同一个 iCloud 帐户)。
有效!数据同步正常。
但是主 UIViewController 的视图没有反映新数据。要查看更改,我必须切换到不同的视图,然后切换回在其 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)
}
很明显,数据正在同步。只是通知没有按预期工作。所以最终用户不会自动看到 new/sync 的数据。
我怎样才能让它工作?
我也遇到了同样的问题。我刚刚发现它在 TestFlight 构建中工作正常,但是当直接使用 Xcode 构建时,它却没有。你试过了吗?
还请记得听取此处概述的远程更改: https://developer.apple.com/documentation/coredata/consuming_relevant_store_changes
这似乎需要 NotificationCenter.default.addObserver
object:
字段为 container.persistentStoreCoordinator
才能工作,这在 https://developer.apple.com/documentation/coredata/consuming_relevant_store_changes.
Apple 在 https://developer.apple.com/documentation/coredata/synchronizing_a_local_store_to_the_cloud 的示例代码使用 object: container
但不起作用。
听众:
NotificationCenter.default.addObserver(self, selector: #selector(handleRemoteChange), name: .NSPersistentStoreRemoteChange, object: nil)
应该加在里面
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
// Here:
NotificationCenter.default.addObserver(self, selector: #selector(handleRemoteChange), name: .NSPersistentStoreRemoteChange, object: nil)
}
不要忘记取消订阅视图将消失:
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
NotificationCenter.default.removeObserver(self, name: .NSPersistentStoreRemoteChange, object: nil)
}
我有同样的问题,通过 在调用 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