ioscore-datansmanagedobjectmanagedobjectcontext

Save object from child NSManagedObjectContext not available in parent


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.


Solution

  • 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.