Recommended way of 'merging' a deleted CKRecord that was changed?

My local database has a table that stores database changes. This is used to track changes made when the current device is offline. Here's my question, what's the recommended way to detect whether or not a delete change should be merged?


So say I have a record titled Note. Device 1 is offline and deletes Note. Now Device 2 is online and edits Note after Device 2 deletes it.


Now Device 1 comes back online and sends the delete to Cloudkit. Ideally, I'd like to get a CKErrorServerRecordChanged error for the delete since Device 2 got an edit to the server and Device 1 is deleting data it never had. If this is the case, I can inspect some other fields on my record and decide how I want to merge (I could use the last write wins. Did the user edit the record on Device 2 after it was deleted on device 1? If so, I can make Device 2 the winner OR I can ask the user what he wants).


BUT you don't specify a CKRecord for deletes. Instead you give a CKModifyRecordsOperation a CKRecordID to delete. And CKRecordIDs don't include a change tag, so I assume the delete will go through even if the save policy is set to CKRecordSaveIfServerRecordUnchanged and the record to be deleted by the current device was changed in between?

Accepted Reply

Yes, a delete will go through even if the change tag would indicate a conflict. It's as if 'delete' wins any conflict.


If that's not the action you want you can first make a 'test' change in a record you want to delete and when (and if) the completion handler returns 'no conflict in change' then you can delete the record (otherwise handle the conflict). The time in between the completion handler returning 'no conflict in change' and your request to 'delete' will be too small for their to be a reasonable chance of creating a new conflict.

Replies

Yes, a delete will go through even if the change tag would indicate a conflict. It's as if 'delete' wins any conflict.


If that's not the action you want you can first make a 'test' change in a record you want to delete and when (and if) the completion handler returns 'no conflict in change' then you can delete the record (otherwise handle the conflict). The time in between the completion handler returning 'no conflict in change' and your request to 'delete' will be too small for their to be a reasonable chance of creating a new conflict.

Thanks for the answer. Sending a dummy change before deleting sounds like the best possible option.


I wonder why they decided to design it that way though. Having a delete go through by default when the record was changed in between by another client seems like a conflict that is at least just as bad, if not worse, than any other conflict. Wonder why they decided to not have the server do the same type of change tag check for deletes.