Conflict resolution and data merging is a tall order.
I had to do a project recently with this same kind of issue doing VCard merging with a webservice.
We have a good paradigm already in the software development world: source control!
You need a version or timestamp with the data that is always updated when the data is edited. You need to store this version id when you check out the data so you know the version you received. Then in your offline app, you need a method for detecting changes that happened locally and flag them in your app (know what was added, removed, or edited locally).
If you have that information, when you are sending up local changes that happened, you can extrapolate that a change occurred remotely on the central server at the same time a user made a local change while offline to the same data. Using that you can bring up some kind of call to action for the user to merge the data.
Below is the logic that used for the webservice I created if it helps.
Sync operation pseudo logic:
1. The client calculates all local changes that have occurred since the last sync according to the local sync data file.
a. Updated contacts - contacts that are different since the last sync according to the local repository’s data
b. New contacts - contacts that are not in the local repository’s data but have appeared since the last sync locally
c. Deleted contacts – contacts in the local repository but are no longer on disk
2. For any updated or deleted contacts, the client will call and check to see if the file was modified on the server since the last time there was a sync locally to try and find any possible sync conflicts.
a. If a file was modified or deleted locally and at the same time modified or deleted on the server since the last sync, then a call to action dialog should be displayed asking the user to choose between updating everything to use the current web service version or the current local version.
i. If user chooses the server change set, then the local version should be overridden with a GET call to the web service
ii. If the user chooses to take the local change, then an update (PUT) or destroy (DELETE) call should made to the web service
b. If the file was not modified remotely then it should automatically be put on the server
3. For any new contacts created, the client should do a new (POST) call to the server automatically for each one and add a new line to its repo mapping the local contact to the GUID returned in the POST call.
4. The client should call to get a list of all the contacts on the server with their revision numbers from the web service using the Get Contacts web service method.
5. The client should then update each local contact to match the server:
a. If a file is on the server that is not locally known, assume a new contact was added, so a GET should be called to pull down that contact.
b. If a file is not on the server that was there previously in our sync repository, assume the contact was deleted, and delete the local contact.
c. If a file is both on the server and local but the revision number is higher on the server, then do a GET to update the local version.