How to Save Data When Using One ManagedObjectContext and PersistentStoreCoordinator with Two Stores How to Save Data When Using One ManagedObjectContext and PersistentStoreCoordinator with Two Stores sqlite sqlite

How to Save Data When Using One ManagedObjectContext and PersistentStoreCoordinator with Two Stores


Thanks to Ray Wenderlich's referral to Mic Pringle, Mic proposed a Managed Object Model architecture with which I was able to solve the issue while adhering to my goals. The key to the solution is utilizing an abstract entity as a parent entity to user and seed entities.

Managed Object Model

With this architecture, it is possible to create two Configurations that are assigned to separate stores:1) UserData - r/w store located in the User's Documents directory.

UserData Configuration

2) SeedData - r only store located in the App Bundle.

SeedData Configuration

The downside is that record ID's must be maintained for the seed data entities (since relationships are not allowed between Configurations), but the huge upside is that changes or additions can be made to the seed data without affecting the user's entries AND without having to adopt any of the cumbersome solutions discussed in the RESEARCH section of the original post of this question.


For the core question of saving data with one context/coordinator and two stores, the approach you want is:

  1. When adding the user-editable store via addPersistentStore, save a reference to the NSPersistentStore object that is returned.
  2. When creating a new object to save in the user-editable store, do something like this:

    NSManagedObject *newObject = [NSEntityDescription insertNewObjectForEntityForName:@"Vehicle" inManagedObjectContext:self.managedObjectContext];[self.managedObjectContext assignObject:newObject toPersistentStore:userEditableStore];

    The key here is to explicitly call assignObject:toPersistentStore: before saving changes.

For related questions:

I would prefer, if at all possible, to do seed data updates without having to manage data versions behind the scenes...

If you leave the non-editable store in the app bundle (i.e. you don't copy the file to somewhere else), you can just include a new version of the data with a new version of the app. You'll always be using whatever version is in the app bundle, so you'll have the latest data.

If you do end up copying data from the seed store to the user store, make sure that each entry includes the app (or seed store) version number when it was added. That'll make it easy to avoid duplicates.

User Data and Seed Data should not contain any duplicate records between the two and use the same ManagedObjectModel. So from data and model perspectives, there should be no need to merge the two stores or migrate one store to another.

You don't need to copy data from one to the other if you don't have any relationships between objects in different stores-- because that's just not permitted in Core Data. If you need relationships (and it sounds like you do) then look into fetched properties. These look a lot like an attribute or a relationship on an entity type, but internally they look up values from the persistent store(s). With multiple persistent store files this allows something that's almost but not quite like a relationship between objects in different stores.