4
votes

In my iOS application, I am attempting to sync core data with a web back end. I want to use a separate background managed object context for the sync so I can keep my main context free to accept changes from the ui while the sync is processing. Both contexts are children of my write-to-disk context as per this blog post http://www.cocoanetics.com/2012/07/multi-context-coredata/.

My question is, how can I merge both children contexts before I save to disk?

If I subscribe to contextDidSaveNotifications, I can merge the contexts using

[mainContext mergeChangesFromContextDidSaveNotification:syncFinishedNotification];

but according to the documentation... "This method refreshes any objects which have been updated in the other context, faults in any newly-inserted objects, and invokes deleteObject:: on those which have been deleted."

I don't want to refresh the updated objects and lose changes made to the mainContext, but rather merge both change sets.

I am new to multi-context core data, so I may be thinking of this in the wrong way.

Any ideas?

1

1 Answers

2
votes

Merging changes in Core Data is always a process of taking changes in one managed object context and then applying them to another context. If both contexts might acquire new changes at the same time, the merge is affected by the context's merge policy. If there are no conflicting changes, there's nothing to worry about. If there might be, though, you'll need to choose an appropriate merge policy.

The default value if you do nothing is NSErrorMergePolicyType, which means that saving changes would fail after merging changes. You almost certainly don't want that. But there are other predefined policies to choose from. NSMergeByPropertyObjectTrumpMergePolicyType is often a good choice here, because gives priority to unsaved conflicting changes. So if the sync context makes conflicting changes to an object the user is editing, the user's changes are preserved. There are a few other canned options. If none of them fit, you can always subclass NSMergePolicy and do whatever you like. That's rarely necessary, though.