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

最后都变了- 提交于 2019-12-06 00:28:31
AnrosApps

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.

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.

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

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!