Search code examples
xcodecore-datansmergepolicy

Coredata Multiple NSMergePolicy


Hello my lovely community, I hope everyone doing well.

I wonder did you ever find your self in a spot that you need to use multiple Merge Policies in the coredata. Therefore using multiple NSManagedObjectContext. Like in the example below:

enter image description here

Lets assume that we have two entities and both entities have a constraint. But you want those constraint handled differently. Like in one you don't want to overwrite but in another you want to overwrite the store with cache or in another you simply want an error raised.

So what approach you are following?

Example: There are 20000 cars in the database in day one. Next day app fetches 1000 new cars. But lets assume 5 of them already in the database and we don't want to update those (mergeByPropertyStoreTrumpMergePolicyType). So when we bulk create/insert 995 cars will be inserted to database. (in total 20995)

And lets assume there are 200 Person in the database and app fetches 10 new persons from backend. And those 10, 5 of them already in our database (same personID). But in this case we want to overwrite Persons in our database. So when we bulk create/insert 10 people 5 of them will be overwritten. (total 205) (mergeByPropertyObjectTrumpMergePolicyType)


Solution

  • Using two different contexts is fine if that's working for you. A couple of other possibilities:

    • If the two API calls are not concurrent, you could use the same context but change the merge policy on the fly. It's not fixed, so you can go back and forth as needed. This is probably what I'd do unless both entities came from the API call or unless I really needed them to run concurrently.
    • A more involved but possibly more satisfying approach would be to build your own custom merge policy by subclassing NSMergePolicy and implementing resolve(optimisticLockingConflicts list: [NSMergeConflict]). Your custom merge code could then merge different entities in different ways. The documentation on this is pretty thin, but this previous answer might help. This is what I'd prefer to do, but the first approach would be quicker to write.