【问题标题】:NSFetchedResultsController with external changes?带有外部更改的 NSFetchedResultsController?
【发布时间】:2015-04-27 22:17:25
【问题描述】:

我正在读取 WatchKit 扩展中的 CoreData 数据库,并从父 iPhone 应用程序更改存储。我想使用 NSFetchedResultsController 来驱动对手表 UI 的更改,但扩展中的 NSFetchedResultsController 不会响应对父应用程序中的存储所做的更改。有没有办法让辅助流程响应第一个流程中所做的更改?

【问题讨论】:

    标签: core-data watchkit


    【解决方案1】:

    要尝试/考虑的一些事情:

    您是否启用了应用程序组? 如果是这样,您的数据存储在主机应用程序和扩展程序之间共享的位置吗? 如果是这样删除缓存的数据,参考here帮助?

    【讨论】:

    • 感谢您的回复。他们正在共享一个应用程序组,并且在发生更改时会发送 Darwin 通知。但是在通知到达时清除缓存,或者清除缓存并执行新的提取不会导致委托函数触发。
    【解决方案2】:

    阅读这个非常相似问题的答案:https://stackoverflow.com/a/29566287/1757229

    还要确保将 stalenessInterval 设置为 0。

    【讨论】:

      【解决方案3】:

      我遇到了同样的问题。如果您想在主应用更新时更新手表应用,我的解决方案适用,但它可以轻松扩展为双向。

      请注意,我在 NSNotificationCenter 上使用了一个简单的扩展,以便能够更轻松地发布和观察 Darwin 通知。

      1。发布达尔文通知

      在我的 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)
          }
      
      })
      

      2。收听 Darwin 通知(但仅在 Watch 上)

      我在同一个类中监听相同的 Darwin 通知,但要确保我在实际的手表扩展上(以避免刷新刚刚更新的上下文)。我没有使用框架(也必须针对 iOS 7),所以我只是在主应用程序和手表扩展上添加了相同的 CoreDataManager。为了确定我在哪里,我使用了编译时标志。

      #if WATCHAPP
          notificationCenter.addObserverForDarwinNotification(self, selector: "resetContext", name: IPCNotifications.DidUpdateStoreNotification)
      #endif
      

      3。重置上下文

      当手表扩展收到通知时,它会重置 MOC 上下文,并发送内部通知告诉 FRC 更新自己。我不知道为什么,但如果没有一点延迟,它就不能正常工作(欢迎提出建议

      func resetContext() {
          self.managedObjectContext?.reset()
      
          delay(1) {
              NSNotificationCenter.defaultCenter().postNotificationName(Notifications.ForceDataReload, object: self.managedObjectContext?.persistentStoreCoordinator)
          }
      }
      

      4。最后,更新 FRCs

      在我的例子中,我在数据结构中嵌入了一个普通的 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)
          }
      }
      

      【讨论】:

        【解决方案4】:

        在 WWDC '17 上,Apple 引入了许多新的 Core Data 功能,其中之一是 Persistent History Tracking 或 NSPersistentHistory。但截至撰写本文时,它的 API 仍未记录在案。因此,唯一真正的参考是What’s New in Core Data WWDC session

        更多信息和示例here

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2014-05-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-11-25
          相关资源
          最近更新 更多