Need iOS Database Cloud Design Tips - iphone

I have an app that uses an SQLite database. With the advent of iCloud on the rise I'm trying to figure out a good architecture for syncing data between devices. So lets say my app runs on an iPhone, an iPad, and a Mac. How can I keep data in my DB up-to-date on all devices?
My first thought was, I can put the database in the cloud and send transactions. But the device may not always been online and the users need their content at anytime, so that wont work. My other thought was to continue using the local db, and then when a connection is made, to send the cached data to the central db. The problem is I have no ideal where to even begin on something like that. How would I know which data has been sent and not sent, which data to actually send when a connection is made, etc.
So this is my question (we don't have to get into iCloud specifics), using an SQLite database and iCloud (or any storage medium), how can I sync data between multiple devices, but still have the most recent data stored locally on the device?

You might want to checkout Couchbase Mobile. This would help with the synchronization you are looking for.
If you have a significant investment into CoreData, then you may want to look at writing your own NSIncrementalStore to support writing data to and from a key value store.
iCloud is only going to be a good solution if your data is sandboxed to a specific user. If you have multiple users that want to view the same data then it won't work.

Related

Syncing data to iPad from iPhone

I want to sync data between iPhone and iPad. I am using core data and save the data in Documents of Document Container. Since Documents is backed up by both iTunes and iCloud. Since iCloud is deprecated in latest version of Xcode. Do I have to do anything else to sync data between these iOS devices?
Backups are not a sync mechanism. For one thing, backups are device specific. Data that gets backed up from someone's iPhone is not available to their iPad. There is no device-to-device data mixing through backups.
Putting the persistent store file in iCloud (via the iCloud file API) is not workable either. You can't just read/write the file in iCloud directly, you need to download the file first and later upload changes. Core Data isn't designed to work in that scenario. You might write code to do it, but the data would become corrupted almost immediately because Core Data isn't expecting you to mess with the persistent store like that.
If you want to sync data between devices, there are many options. Apple offers CloudKit, which is free and supported by Apple. Firebase is popular. Parse servers are still extremely common even though Parse itself is shutting down. Add to that Microsoft Azure and many, many others.

Coredata iPhone to iPad/Mac with iCloud?

We have finished writing an iPhone App that uses coredata.
In further versions we plan to add an iPad App that is able to display the data collected by the iPhone App (and of corse modify, use it) to give more interaction possibilities to the user.
My question is: Is it possible to move existing coredata (of already installed apps on iphones) to the cloud and read that data out with an iPad application?
If yes: can you point me in the right direction of where to start?
If no: is there another alternative to access coredata created with an iPhone App with an iPad app?
When using Core Data's built in iCloud support it doesn't matter what kind of device you're on, only that the Core Data stack is initialized the same way. Any iOS device or Mac can use the same iCloud store, and data created on one can be read on another.
One crucial detail though: If you already have a data store and you add iCloud support, those pre-existing records do not automatically get migrated to the cloud. iCloud works based on transaction logs, and transaction logs are only created when you save changes. Existing data that doesn't immediately change generates no transactions, and therefore doesn't go to the cloud.
If you have existing data when you add iCloud, you'll need to migrate the data to a new data store to force transactions for those existing records. You can do this fairly easily using NSPersistentStoreCoordinator's migratePersistentStore:toURL:options:withType:error: method. It's not hard, but it's not always obvious that it's necessary.
To get started, I first suggest watching Apple's WWDC videos on iCloud-- especially WWDC 2012's session 227, Using iCloud with Core Data. Next, I suggest extreme caution, because as of today Core Data's iCloud support is still, shall we say, far from being the most reliable of Apple's APIs.

iPhone (iOS) app using local sqlite and desire to sync between multiple devices

I have an iPhone (iOS) app that keeps data in a local SQLite database on each device. The app is used to manage a virtual bank account for kids to track their allowance, spending, savings, etc. (KidsBank and KidsBank Free). I am getting a lot of requests from parents to provide a sync capability between parents and possibly even their children's iOS devices.
I have considered several options, but all are tedious and non-trivial since this basically requires database replication or a new architecture. Any transaction on any device ideally should appear (sync) to all devices in the family (as immediately as possible).
Ideally, I would like the sync to be automatic & hands off
Options include
(1) Use of iCloud
(2) Use a direct network connection between devices (wifi)
(3) Use of a server side database and web service (JSON/RESTFul)
(1) iCloud
PRO: iCloud provides distributed file sync
CON: iOS 5 required, SQLite database files can not be synced via iCloud, classic database replication (and non-trivial)
Using iCloud is a strong consideration. Devices can write a custom transaction log to an iCloud file where there is one file for each device identified by a unique device ID. Global unique ids (GIDs) and last change timestamps are added to each table. All participating devices will write a unique device ID to a separate file in iCloud. Upon app launch or upon log file change, the app running on a specific device will load all transactions but not those generated on their own device from the files via iCloud. The last participating device to load the transaction will remove the transaction from the file. If the device is not the last participating device, it simply signs off on the transaction and allows the file to sync via iCloud. There may be better algorithms, but the basic idea is the same - using iCloud to push around change logs.
(2) A direct wifi connection will allow two devices to manually sych.
PRO: Not as complicated to manage the sync process
CON: Users must both select to sync from their apps while connected on wifi
(3) Move the entire database or manage transactions on a server.
PRO: Sync is no longer required
CON: Typical issues for a web-driven app. Would need to rewrite the database service layer (currently in SQL) to use a remote web service. Cost of running a server (I would use AWS).
Can anyone offer some experience in syncing SQLite between multiple devices? I'm leaning in the direction of using iCloud to push around transaction logs. I'm trying to minimize cost and complexity.
Moving to iCloud is probably the best solution, as it is proven and made by Apple. You don't need to worry to much about the iOS 5 requirement, as according to most stats over 90% use it. iOS 5 is free to upgrade to. You could then rename your old version as Lite, and continue without syncing.
Syncing is probably one of the hardest things you do.
One solution I made is that all changes to a database leave a log, with timestamp, uniqueid and couple of other things to make sure the transaction is totally anonymous and totally unique. I have made an extremely simple web service that has two operations, you can add transaction to it, so I sync whenever the user is on wifi, so I push all changes, receive a result from the server, then delete the transaction records as they are synced.
The other action is to fetch the records, send the timestamp of last sync, userid and other.
All data is sent using JSON and received as such. It can easily handle tens of thousands of users, running on a small Amazon EC2 server.
This is pretty much how iCloud works, but I made this solution before iCloud. Now I am going to iCloud, but probably need to keep the server running for 1 more year or so, depends on usage.
Hope this helps you.
After finding time to get back to working on the app and also with time passing and Core Data iCloud replication maturing, I converted my app to Core Data (NSSQLiteStoreType) and monitor notifications such as persistentStoreDidImportUbiquitousContentChanges. Using lightweight migrations too. Working well.

how to synchronize coredata between devices?

i have an iphone app that uses coredata to store its contents. users often ask me if i could provide a way to sync data between their mobile devices (ipod/iphone/ipad). as of now, i have no idea on how to achieve this.
i found zsync, but this seems to depend on a osx version of the app (which i dont have). i also read about upcoming iclouds sync features, and it seems to be what i need - however i think its not possible to sync coredata contents, but text-based contents only (e.g. xml storage files). is this true?
another way i was thinking of was to abuse the eventkit api to sync via a user-provided calendar. since my app is mainly managing events, which can optionally be stored in a user-calendar (in addition to coredata storage), syncing through a calendar would seem good to me. however i think syncing might break, e.g. when the user chooses not to syncronize the whole calendar but only like 3 months in the devices settings/account settings.
anyone got an idea of how my approach should be like? any tips?
Syncing device to device (if that is what you are trying to achieve) can be quite tricky. You could implement your own discovery and data-transfer protocol and work something out that way, but it could be quite a bit of work.
Syncing device to server to device is a bit more straightforward, assuming that you already have a server with some form of registration/login system. Then you just need a way of communicating your current database state up to the server, and then back down again from the server to other devices. Again there is a fair bit of work involved in doing this, but at least the logic of working out which devices sync with which other devices and how they transfer data from one to the other is all implicit in the workings of the server.
As for iCloud, the programmatic content that you sync through it needs to be derived from UIDocument, so it will not help you with generic Core Data entities.
If you're looking for an out-of-the-box solution that will sync all of your Core Data content from one device to another with no custom code, then there really isn't one. The closest you can reasonably get would be to ship the entire .sqlite file that your app uses from one device to another, overwriting the target devices .sqlite file. That works fine if your sync only needs to be unidirectional, but obviously is not appropriate for other use-cases. Perhaps you could use this model with iCloud, if you can get it to sync your app's entire .sqlite file as an atomic entity.

Best practice for sending data updates to iPhone app?

I'm currently in the middle of developing an iPhone app with a big reference database (using Core Data backed with a pre-populated sqlite database). Once the app is live and deployed to a client's iPhone, I need the facility to update/insert a small amount of data. What are best practices / methods for doing this?
There may be occassions when the frequency of updates will be daily for a month or so. Other occassions when a data update happens once every few months.
What is the recommended way of doing this? Note, I don't anticipate any data model changes for these updates -- this is purely an insert/update of data.
At the moment I'm starting to research the use of push data notifications (q:payload size restrictions?), app store updates (q:code/data model only, not data updates?) and the use of my own ad hoc data server (which the app connects to routinely to check for updates).
Can anyone please provide me any pointers on the above?
Thanks in advance
IIRC Push Notifications have a maximum payload of 256 bytes. Enough for notification purposes, but not more. Your app would still have to download the actual data from your own server after receiving the notification.
Note that the app bundle is not writable on the device. So if your app needs to update the data store, you should copy the pre-populated database file from the app bundle to the app's documents directory on first launch.
App Store updates would certainly be feasible (especially now that Apple seems to have gotten its review process down to a few days at most) but note that an App Store update will always replace the entire app bundle (code and data), so if your pre-populated reference database is big, the customer would have to download it in full every time.