views:

571

answers:

4

I have a Core Data app that will end up being an iPhone/iPad universal application.

I would like to implement cloud syncing so that an iPhone and an iPad both running the app could share data. I'm planning to use the recently released Dropbox API. Does anyone have any thoughts on the best way to go about doing this? The Dropbox API allows for apps to store files on the cloud. What I was thinking was to original store the database (sqlite) for the app on the cloud and then download that database, but I then realized that using that method would make it painfully difficult to merge changes (rather than replacing the whole database).

Any thoughts are appreciated. Thanks.

A: 

You might look into GameKit to share data. Otherwise it seems like you'll just need to manage synchronization with an intermediate file server.

Alex Reynolds
I was considering that option, but what's the easiest way to merge changes between 2 Core Data databases?
macatomy
The iPhone doesn't support Sync Services available to OS X ( http://developer.apple.com/iphone/library/technotes/tn2009/tn2152.html#SECSYNCING ) so you'll need to write your own routines. Look into adding a timestamp to records and allowing the user to decide the policy for how syncs proceed (for example, newest timestamp-ed record gets sent to all other devices).
Alex Reynolds
+1  A: 

You may want to use a different method for synchronization. What is the type of data that you will be dealing with?

I've had much success using a lightweight rails back-end.

jessecurry
Just some simple model objects (basically consisting of NSStrings, NSArrays, etc)
macatomy
If you're comfortable with rails check out the ObjectiveResource project.
Frank Schmitt
I regret that I only have one upvote to give Frank Schmitt's comment.
corprew
A: 

You probably want to export the data to some format other than the native sqlite format. If I were designing something like this, I think JSON would probably be my format of choice.

I haven't looked at the dropbox API, but they support uploading and downloading file differences, rather than the whole file, right? Depending on how the API works, maybe having your application understand their "diff" format and working with that might be easier...

Mark Bessey
Converting the data to JSON wouldn't be a problem. The issue that I still have is how to merge the changes between the two libraries effectively.
macatomy
Sync is a generally hard problem, unfortunately. If you want to sync in both directions, you'll need to keep some kind of modification count for each record, and take the "latest" version when merging. The real challenge comes in handling conflicts in a reasonable way.
Mark Bessey
Thats what I assumed, I need to figure out a way to resolve conflicts. One specific scenario I'm thinking of is that if device A had a record but then was deleted and device B has that record but it isn't deleted, I wouldn't want device A to get that record back when synced.. this is tough
macatomy
+2  A: 

If you can get away with it, the easiest way to do synchronization (by far) is to have three copies of your data locally: the copy you last uploaded ("old"), the copy produced by local changes ("mine") and the copy now downloaded from the server ("theirs").

Then, sort all the records in all three files and walk through them one by one:

  • if old == mine, use theirs
  • else if old == theirs, use mine
  • else you have a conflict; do something about it (eg. always use mine, aka "last writer wins")

Note that "mine" or "theirs" or "old" might not exist. The rules above still apply in that case; if the result you choose is "does not exist", then you'll want to delete the record in the output file.

Finally, upload the resulting file back to the server so that it will be the "theirs" database for the next guy. Then copy the new file to your local "old" and "mine" databases.

(There are more space-efficient algorithms than the above... but there aren't any easier ones :) And disk space is pretty cheap nowadays, particularly if you compress the files.)

apenwarr