Saving CoreData objects

The context

I am quite new at using Core Data.
I have started to use it just a few months back, and I’ve been using it extensively the last couple of months.
During this time, I have learned some things about NSManagedObjectContext that I want to share.
Here, I’ll explain how the saving mechanism works with multiple contexts created using different methods.

We’ll work with a very basic Core Data model which will contain only one single entity.

Here is the first important lesson to learn.
Let’s have a look at the official documentation of save():

Attempts to commit unsaved changes to registered objects to the receiver’s
parent store.

This can be misleading. When one see parent store he can understand the parent persitent store of my context hierarchy.
However, what is meant by parent store is either:

the persistentStoreCoordinator

the parentContext

So, if your context was setup with a parent context, changes are commited to his parent but no further.
To save it to the persistent store, you’ll need to call save() on contexts all the way up in the hierarchy until you reach the persistent store.

Then, to prevent “Billy” to be saved while we just want to save “John”, we will not create our editing context as a child of the main.
We will create what we’ll call a sibling context. These are contexts that share the same persitent store coordinator:

Conclusion

calling save() on a context will only send changes one step up the hierarchy

save() will commit changes contained in the whole context

I hope that this may help anyone who did not yet grasp how Core Data save its content throught contexts.

As a side note: for the sake of simplicity here, we have only worked with entity insertion.
When you start playing with entity attributes, you’ll need to perform some refreshObject(_:mergeChanges:) calls to see the saved values in other contexts.

createPersistentStoreCoordinator and addPersonToContext are helper functions to shorten the code in the article. You can find the code here↩↩2

Note that you should use performBlock() to execute calls on a NSManagedObjectContext to ensure that the correct thread is using it. ↩