【发布时间】:2015-04-27 22:17:25
【问题描述】:
我正在读取 WatchKit 扩展中的 CoreData 数据库,并从父 iPhone 应用程序更改存储。我想使用 NSFetchedResultsController 来驱动对手表 UI 的更改,但扩展中的 NSFetchedResultsController 不会响应对父应用程序中的存储所做的更改。有没有办法让辅助流程响应第一个流程中所做的更改?
【问题讨论】:
我正在读取 WatchKit 扩展中的 CoreData 数据库,并从父 iPhone 应用程序更改存储。我想使用 NSFetchedResultsController 来驱动对手表 UI 的更改,但扩展中的 NSFetchedResultsController 不会响应对父应用程序中的存储所做的更改。有没有办法让辅助流程响应第一个流程中所做的更改?
【问题讨论】:
要尝试/考虑的一些事情:
您是否启用了应用程序组? 如果是这样,您的数据存储在主机应用程序和扩展程序之间共享的位置吗? 如果是这样删除缓存的数据,参考here帮助?
【讨论】:
阅读这个非常相似问题的答案:https://stackoverflow.com/a/29566287/1757229
还要确保将 stalenessInterval 设置为 0。
【讨论】:
我遇到了同样的问题。如果您想在主应用更新时更新手表应用,我的解决方案适用,但它可以轻松扩展为双向。
请注意,我在 NSNotificationCenter 上使用了一个简单的扩展,以便能够更轻松地发布和观察 Darwin 通知。
在我的 CoreData 存储管理器中,每当我保存主托管对象上下文时,我都会发布一个 Darwin 通知:
notificationCenter.addObserverForName(NSManagedObjectContextDidSaveNotification, object: self.managedObjectContext, queue: NSOperationQueue.mainQueue(), usingBlock: { [weak s = self] notification in
if let moc = notification.object as? NSManagedObjectContext where moc == s?.managedObjectContext {
notificationCenter.postDarwinNotificationWithName(IPCNotifications.DidUpdateStoreNotification)
}
})
我在同一个类中监听相同的 Darwin 通知,但要确保我在实际的手表扩展上(以避免刷新刚刚更新的上下文)。我没有使用框架(也必须针对 iOS 7),所以我只是在主应用程序和手表扩展上添加了相同的 CoreDataManager。为了确定我在哪里,我使用了编译时标志。
#if WATCHAPP
notificationCenter.addObserverForDarwinNotification(self, selector: "resetContext", name: IPCNotifications.DidUpdateStoreNotification)
#endif
当手表扩展收到通知时,它会重置 MOC 上下文,并发送内部通知告诉 FRC 更新自己。我不知道为什么,但如果没有一点延迟,它就不能正常工作(欢迎提出建议)
func resetContext() {
self.managedObjectContext?.reset()
delay(1) {
NSNotificationCenter.defaultCenter().postNotificationName(Notifications.ForceDataReload, object: self.managedObjectContext?.persistentStoreCoordinator)
}
}
在我的例子中,我在数据结构中嵌入了一个普通的 FRC,所以我在 FRC 范围之外添加了观察者。无论如何,您可以轻松地继承 NSFetchedResultsController 并在其 init 方法中添加以下行(记住停止观察 dealloc)
NSNotificationCenter.defaultCenter().addObserver(fetchedResultController, selector: "forceDataReload:", name: CoreDataStore.Notifications.ForceDataReload, object: fetchedResultController.managedObjectContext.persistentStoreCoordinator)
和
extension NSFetchedResultsController {
func forceDataReload(notification: NSNotification) {
var error : NSError?
if !self.performFetch(&error) {
Log.error("Error performing fetch update after forced data reload request: \(error)")
}
if let delegate = self.delegate {
self.delegate?.controllerDidChangeContent?(self)
}
}
【讨论】:
在 WWDC '17 上,Apple 引入了许多新的 Core Data 功能,其中之一是 Persistent History Tracking 或 NSPersistentHistory。但截至撰写本文时,它的 API 仍未记录在案。因此,唯一真正的参考是What’s New in Core Data WWDC session。
更多信息和示例here
【讨论】: