ios - NSManagedObject 更改未反射(reflect)在 WatchKit 扩展中

标签 ios swift core-data watchkit

我正在构建一个 Apple Watch 应用程序,它通过 App Group 在 iPhone 目标和 Watch 目标之间共享核心数据上下文。下面的 WatchCoreDataProxy 是一个处理 Core Data 功能的自定义框架,将 App Group 称为两个目标之间的桥梁。我更新 iPhone 应用程序中的上下文并保存,然后将 Darwin 通知发布到 Watch,它从同一上下文获取更新的 NSManagedObjects。除了一个怪癖外,大多数一切都运行良好:

我在 Watch 中获取的 NSManagedObject(我们称它为 Parent)包含与另一个 NSManagedObject(我们称它为 Child)的一对多关系。我正在从 Watch 目标中获取 Parent,并假设它的属性已保存到 Core Data 并反射(reflect)最新值。

Parent 的属性始终反射(reflect)从 Watch 获取时的更新值。但是 Child 关系对象没有。真正奇怪的是,对 Child 的更改会持续存在于 iPhone 应用程序方面,但不会存在于 Watch 中。我从 Watch 获取对象的代码如下所示:

let entityDesc = NSEntityDescription.entityForName("Parent", inManagedObjectContext: WatchCoreDataProxy.sharedInstance.managedObjectContext!)
let request: NSFetchRequest = NSFetchRequest()
request.entity = entityDesc

let predicate = NSPredicate(format: "loadedOnWatch == 1")
request.predicate = predicate

var error: NSError?
let array = WatchCoreDataProxy.sharedInstance.managedObjectContext!.executeFetchRequest(request, error: &error)! as NSArray

let parent: Parent = array[0] as! Parent
self.parentID = parent.objectID
self.parentTitleLabel.setText(parent.name)   //reflects changes successfully

self.childArray = parent.children.sortedArrayUsingDescriptors([NSSortDescriptor(key: "position", ascending: true)]) as NSArray
let firstChild = self.intervalArray.objectAtIndex(0) as! Child

let title = firstChild.title
self.childTitleLabel.setText(title)    //does not reflect changes

我试过 Core Data 的 refreshObject:mergeChanges: 方法,但没有成功。为什么 Watch 目标不反射(reflect)在同一托管对象上下文中对 Child 所做的更改?

更新

通过重写上面的代码,我发现通过两个不同的 NSFetchRequests 分别获取 NSManagedObjects,然后刷新对象会产生正确的值。这是更新后的代码:

// Parent fetch
let parentEntityDesc = NSEntityDescription.entityForName("Parent", inManagedObjectContext: WatchCoreDataProxy.sharedInstance.managedObjectContext!)
let parentRequest: NSFetchRequest = NSFetchRequest()
parentRequest.entity = parentEntityDesc

let parentPredicate = NSPredicate(format: "loadedOnWatch == 1")
parentRequest.predicate = parentPredicate

var parentError: NSError?
let array = WatchCoreDataProxy.sharedInstance.managedObjectContext!.executeFetchRequest(parentRequest, error: &parentError)! as NSArray

let parent: Parent = array[0] as! Parent
self.parentTitleLabel.setText(parent.name)

// Child fetch
let childEntityDesc = NSEntityDescription.entityForName("Child", inManagedObjectContext: WatchCoreDataProxy.sharedInstance.managedObjectContext!)
let childRequest: NSFetchRequest = NSFetchRequest()
childRequest.entity = childEntityDesc

let childPredicate = NSPredicate(format: "parent = %@", parent)
childRequest.predicate = childPredicate

let sort = NSSortDescriptor(key: "position", ascending: true)
childRequest.sortDescriptors = [sort]

var error: NSError?
self.childArray = WatchCoreDataProxy.sharedInstance.managedObjectContext!.executeFetchRequest(childRequest, error: &error)! as NSArray
let firstChild = self.childArray[0] as! Child
WatchCoreDataProxy.sharedInstance.managedObjectContext?.refreshObject(firstChild, mergeChanges: true)

let childTitle = firstChild.title
self.childTitleLabel.setText(childTitle)

那么,为什么以这种方式获取 NSManagedObjects 会产生正确的值,而不是依赖于父级的关系?

最佳答案

这取决于您的 NSManagedContext 的结构。 在 iPhone 应用程序中保存对“某些”NSManagedObject 上下文的更改是不够的,因为在 WatchKit 扩展中,实际上有不同的上下文(它是不同应用程序容器中完全不同的应用程序)。

因此您必须将更改更新到 Persistence Coordinator 中,它实际上将更改保存到应用程序组容器中的文件或 iCloud 中。

关于ios - NSManagedObject 更改未反射(reflect)在 WatchKit 扩展中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29905957/

相关文章:

ios - 使用 iTunesConnect TestFlight 添加测试人员

ios - 当我的服务器看到一些数据到我的 iPhone 时,套接字是唯一的选择吗?

ios - 在导航单元格时将 collectionView 单元格中的 textView 设为第一个响应者

swift - Core Data (Magical Record) + WatchKit Extension + Cocoa Touch Framework

ios - NSMergeConflict(两个线程) - 设置合并策略无法解决

ios - 来自 App Delegate 的启动任务并避免竞争条件的策略

ios - 如何在 Xcode 中使元素成为百分比宽度

ios - 从模态 ViewController 呈现 UIImagePickerController

ios - 使用 Apple 登录按钮标题始终显示 "SIGN_IN_WITH_APPLE"

iphone - NSManagedObjectContext executeFetchRequest 返回不稳定的对象,导致 EXC_BAD_ACCESS、SIGABRT 等