Core data NSFetchedResultsController是否具有外部更改?
我正在WatchKit扩展中读取CoreData数据库,并从父iPhone应用程序更改存储。我想使用NSFetchedResultsController驱动对监视UI的更改,但扩展中的NSFetchedResultsController不响应对父应用程序中的存储所做的更改。有没有办法让第二个流程响应第一个流程中所做的更改?一些需要尝试/考虑的事情: 是否已启用应用程序组? 如果是,您的数据存储是否位于主机应用程序和扩展之间共享的位置?Core data NSFetchedResultsController是否具有外部更改?,core-data,watchkit,Core Data,Watchkit,我正在WatchKit扩展中读取CoreData数据库,并从父iPhone应用程序更改存储。我想使用NSFetchedResultsController驱动对监视UI的更改,但扩展中的NSFetchedResultsController不响应对父应用程序中的存储所做的更改。有没有办法让第二个流程响应第一个流程中所做的更改?一些需要尝试/考虑的事情: 是否已启用应用程序组? 如果是,您的数据存储是否位于主机应用程序和扩展之间共享的位置? 如果删除缓存数据有帮助,请阅读以下类似问题的答案: 还要确保
如果删除缓存数据有帮助,请阅读以下类似问题的答案:
还要确保将
stalenessInterval
设置为0。我也遇到了同样的问题。如果您想在主应用程序更新中更新watch应用程序,则我的解决方案适用,但它可以轻松扩展到双向
请注意,我在NSNotificationCenter上使用了一个简单的扩展,以便能够更轻松地发布和观察Darwin通知
1.发布达尔文通知
在我的CoreData store manager中,每当我保存主托管对象上下文时,我都会发布一条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)
}
})
2.收听达尔文通知(但仅在监视中)
我在同一个类中侦听相同的Darwin通知,但要确保我在实际的watch扩展上(以避免刷新刚刚更新的上下文)。我没有使用框架(也必须针对iOS 7),所以我只是在主应用程序和手表扩展上添加了相同的CoreDataManager。为了确定我在哪里,我使用编译时标志
#if WATCHAPP
notificationCenter.addObserverForDarwinNotification(self, selector: "resetContext", name: IPCNotifications.DidUpdateStoreNotification)
#endif
3.重置上下文
当watch extension收到通知时,它会重置MOC上下文,并发送一个内部通知,通知FRC进行自我更新。我不知道为什么,但如果没有一点延迟,它就不能正常工作(欢迎建议)
4.最后,更新FRC
在我的例子中,我在数据结构中嵌入了一个普通的FRC,所以我在FRC范围之外添加了观测者。无论如何,您可以轻松地将NSFetchedResultsController子类化,并在其init方法中添加以下行(记住停止观察dealloc)
及
在2017年的WWDC上,苹果推出了许多新的核心数据功能,其中之一就是持久历史跟踪(Persistent History Tracking)或NSPersistentHistory。但在撰写本文时,它的API仍然没有文档记录。因此,唯一真正的参考是
更多信息和示例感谢您的回复。他们正在共享一个应用程序组,并且在发生更改时会发送一个Darwin通知。但是,在通知到达时清除缓存,或者清除缓存并执行新的获取不会导致委托函数启动。
func resetContext() {
self.managedObjectContext?.reset()
delay(1) {
NSNotificationCenter.defaultCenter().postNotificationName(Notifications.ForceDataReload, object: self.managedObjectContext?.persistentStoreCoordinator)
}
}
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)
}
}