Hacker News new | ask | show | jobs
by evanspa 3185 days ago
In my strength-tracking iOS app Riker, I use SQLite directly (not CoreData) as my local data store, and support full offline-mode. The backend is Postgres.

In the app, for each relation (e.g., a "workout set"), I have 2 tables: a master and a scratchpad. When a user saves a set, a row is written to the scratchpad table. When the user syncs it with the server, a row is written to the master table and deleted from the scratchpad table. When the user wants to edit the record, I first copy it down from the master table to the scratchpad table. All local editing impacts the scratchpad row. When the user wants to sync, only if a 200 response is returned will I copy-up the scratchpad row to the master row. If the set was edited on another device and the local copy is out-of-sync, the server would have responded with a 409 (http conflict code), and the body would contain the server copy, which is then written to the master table. The user can then figure how they want to merge the scratchpad row and the master row.

Anyway...trying to do all this with CoreData would have been a pain, so I use SQLite directly, and works great.

Or to summarize, I handle offline mode, syncing and conflict detection using "updated_at" timestamp columns along with logic in my REST API to returned appropriate HTTP status codes, interpret "if-unmodified-since" headers, etc.

https://itunes.apple.com/us/app/riker/id1196920730?mt=8

Riker on Android is currently in-progress...

1 comments

I find it difficult to get full offline-mode + sync working correctly. Don't know if you have duplicates in the remote db but I think your approach has a problem: the app send the data (from scratchpad table) to server, the server saves it in DB but the connection drops on device (ex bad connection, user turn off WIFI/3G while syncing) so the app will never get a 200 response. In this case your new data was saved on server but it remains on scratchpad table. On next sync the data will be uploaded as being new: this will cause duplicates.
You are right. The way I solved for this scenario is that when a record is first created on the device, a GUID is created for it (and stored using another column of course). When POSTing new records to the server for syncing, the server will check the GUID and see if the record already exists in its database, and if so, can ignore it (so the duplicate isn't written).

But yes, you're right overall - full offline mode w/syncing, etc is a big pain :)