i'm building apple watch app shared core data context between iphone target , watch's target via app group. watchcoredataproxy
below custom framework handles core data functions, referring app group bridge between 2 targets. update context in iphone app , save, post darwin notification watch fetches updated nsmanagedobjects same context. working except 1 quirk:
the nsmanagedobject i'm fetching in watch (let's call parent
) contains one-to-many relationship nsmanagedobject (let's call child
). i'm fetching parent
within watch target assumption it's properties have been saved core data , reflect recent values.
the properties of parent
reflect updated values when fetched watch. child
relationship object not. what's weird changes child
persist on iphone app side of things, not in watch. code fetch object watch looks this:
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)! nsarray let parent: parent = array[0] as! parent self.parentid = parent.objectid self.parenttitlelabel.settext(parent.name) //reflects changes self.childarray = parent.children.sortedarrayusingdescriptors([nssortdescriptor(key: "position", ascending: true)]) nsarray let firstchild = self.intervalarray.objectatindex(0) as! child let title = firstchild.title self.childtitlelabel.settext(title) //does not reflect changes
i've tried core data's refreshobject:mergechanges:
method no luck. why watch target not reflect changes made child
in same managed object context?
update
i found out re-writing above code fetching nsmanagedobjects separately through 2 different nsfetchrequests, , refreshing objects yields correct values. here's updated code:
// 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)! 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)! nsarray let firstchild = self.childarray[0] as! child watchcoredataproxy.sharedinstance.managedobjectcontext?.refreshobject(firstchild, mergechanges: true) let childtitle = firstchild.title self.childtitlelabel.settext(childtitle)
so why fetching nsmanagedobjects way yield correct values opposed relying on parent's relationship?
it depends on how nsmanagedcontext's structured. it's not enough save changes "some" nsmanagedobject context in iphone app, because in watchkit extension, there different context (it's different app in different app container).
so have update changes persistence coordinator saves them file in app group container or icloud.