NSManagedObject更改未反映在WatchKit扩展中

时间:2015-04-27 21:08:54

标签: ios swift core-data watchkit

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

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

Parent的属性始终反映从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目标不会反映在同一个托管对象上下文中对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会产生正确的值而不是依赖于Parent的关系呢?

1 个答案:

答案 0 :(得分:3)

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

因此,您必须将更改更新为持久性协调器,实际上将其保存到应用程序组容器或iCloud中的文件中。