drewmccormack / ensembles

A synchronization framework for Core Data.
MIT License
1.63k stars 131 forks source link

Constraint conflicts resolution #210

Closed pronebird closed 8 years ago

pronebird commented 8 years ago

Hi,

I've got thousands of conflicts related to unique constraints. Is there any way to provide Ensembles with an instance of NSMergePolicy? I seem to have it set up on my own contexts but that does not count apparently.

pronebird commented 8 years ago

I guess I overlooked that delegate provides

- (BOOL)persistentStoreEnsemble:(CDEPersistentStoreEnsemble *)ensemble didFailToSaveMergedChangesInManagedObjectContext:(NSManagedObjectContext *)savingContext error:(NSError *)error reparationManagedObjectContext:(NSManagedObjectContext *)reparationContext;
inPhilly commented 7 years ago

@pronebird I'm confused about what you are doing to provide Ensembles with an instance of NSMergePolicy in persistentStoreEnsemble: didFailToSaveMergedChangesInManagedObjectContext: error: reparationManagedObjectContext. Can you elaborate a bit? I have set the merge policy on my own context, but if I need to provide something else to ensembles, I want to make sure to provide it.

drewmccormack commented 7 years ago

We don’t actually use a merge policy, though it may be possible to use one manually yourself.

See the book at http://leanpub.com/ensembles http://leanpub.com/ensembles for details.

In short, you can see what changes have been made by Ensembles in the savingContext. If you want to make changes, you refetch those objects in the reparation context, and make the changes there. That way, Ensembles can get a snapshot of the changes you made.

Drew

On 26 Apr 2017, at 06:18, mommyme notifications@github.com wrote:

@pronebird https://github.com/pronebird I'm confused about what you are doing to provide Ensembles with an instance of NSMergePolicy in persistentStoreEnsemble: didFailToSaveMergedChangesInManagedObjectContext: error: reparationManagedObjectContext. Can you elaborate a bit? I have set the merge policy on my own context, but if I need to provide something else to ensembles, I want to make sure to provide it.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/drewmccormack/ensembles/issues/210#issuecomment-297233522, or mute the thread https://github.com/notifications/unsubscribe-auth/AAEuAAumLpOwgPhwKtqaE2UYBPsq4levks5rzsWFgaJpZM4G8V9W.

pronebird commented 7 years ago

@mommyme unfortunately that part of the book is not finished yet. However, as @drewmccormack pointed out and I wish I had that code handy to demo the solution but it's buried somewhere under thousands of commits and not being used anymore.

In short you can re-fetch objects in conflict in reparation context and fix them. I am sure you can also set up merge policy for reparation context, but IIRC you don't save that context, instead simply return YES from delegate method.

Reparation context (at least back in a day) has been a child context of savingContext, therefore all changes in reparation context should bubble up to saving context on next save attempt.

drewmccormack commented 7 years ago

What @pronebird is saying is correct: the reparation context is a child of the saving context. You should not save it — Ensembles will do that. The reason we do it this way is so that Ensembles can see what you changed to make the repairs, and can include those changes for other devices in the sync.

Procedure is this:

  1. Use performBlockAndWait: to the validity of the unsaved data in saving context. If you find objects that are invalid, put their objectID in an array.
  2. In a separate performBlockAndWait: for the reparation context, fetch the invalid objects using the objectIDs you put in the array. Go through them, and 'fix' them, making them valid (a merge policy could probably do this, but you can also just make the changes directly). Do not save.

That's it. Ensembles will save the reparation context, fixing the objects, and it will also record what you changed.