3

I'm having trouble with a parent/child managed object context in iOS. I recall a standard use case is to use a temporary child managed object context, so that the user can decide to press save and propagate the changes up to the parent through save() calls, or the user's changes can be abandoned by letting the child Moc disappear.

I create the child like this:

childMoc = NSManagedObjectContext(concurrencyType: .PrivateQueueConcurrencyType)
childMoc.parentContext = parentMoc

And then I create an object in the childMoc using

let objectInChildMoc = NSEntityDescription.insertNewObjectForEntityForName(...

After I finish populating my shiny new object with all its necessary variables and a couple of dependent objects, I use this code in Swift to attempt to access the new object from the Parent context:

childMoc.performBlock({
    do {
        try childMoc.save()     
        parentMoc.performBlock({
            do {
                try parentMoc.save()                
                do {
                    let objectInParentMoc = try parentMoc.existingObjectWithID(objectInChildMoc.objectID) as? TheRightType                  
                } catch {
                    print("Couldn't find object in parent")
                }       
            } catch {
                print("Couldn't save parent")
            }
        })  
    }
    catch {
        print ("Couldn't save child")
    }
})

I always get "Couldn't find object in parent". What am I missing? I see old example code that uses NSManagedObjectContext save notifications, but I read that those aren't necessary anymore with the parent-child Managed Object Context. The above code is based on recent ObjectiveC code that people claim works (but with the try/catch stuff of swift thrown around it.) For example, this link Correct implementation of parent/child NSManagedObjectContext suggests to me that the above setup should work.

Community
  • 1
  • 1
music_and_cities
  • 147
  • 1
  • 13
  • Just to clarify -- the object IS saved in the parent MOC. If I do a fetch later I find it. So, the existingObjectWithID seems to be the wrong method to find an object in a parent Managed Object Context. – music_and_cities Aug 17 '16 at 20:24
  • I tried skipping the entire `existingObjectWithID` call, and the code seems to work until such time that we try to delete an object, then it complains about having to delete an object from within the wrong context. – music_and_cities Aug 18 '16 at 02:19

1 Answers1

2

Alright, it's a bug! Known bug for many years, but only documented in StackOverflow. The answer is here https://stackoverflow.com/a/11996957/2073793

One needs to obtain permanent object ids using obtainPermanentIDs(for:) before saving in the child context. Then, those permanent ObjectIds can be used to retrieve the objects from within the parent context.

Community
  • 1
  • 1
music_and_cities
  • 147
  • 1
  • 13