What is the most effective to sync all the data present in my server with the database in my ipad application? - ios

I have a lot of data present in the database present in my webserver. Each time I starts the ipad application after downloadiding, I want all these data to be copied into the sqlite database present in my application. Then using this data, the application should work.
We are now using xml's and sometimes on 3g it takes about 20minutes which is completely unacceptable. After the 1st time it syncs using time log and all. And it works without any problem.
Is there any other way I could get all the data and make it populated into my sqlite db?

If it is a large database it might be worth doingin the background. And even better if it was just over wifi (otherwise you'll be eating up your users data)
What I usually do is have a local copy of the database shipping with the app, so the user can use that, and update it in the background. It might be worth creating some pages where you just present the updated content, download that, then update your database accordingly. Rather than downloading everything all the time.
This would depend entirely on your implementation however.

On initial app launch you could download just enough data to make the app functional. Then download the rest of the data in the background.
This is a common strategy used by Sync Frameworks and works pretty well. I have personally tried with with synchronizing more than a thousand objects using OpenMobster's sync service.
Now what data to download initially is to be decided by the requirements of the App
Thanks

Related

Sqlite with (CloudKit or iCloud Drive)

I have an iOS app that timestamps some events and loads them in UI. To persist the data I use CloudKit which is quite fine and fast enough for my use case.
1st problem is, when an event occures I save it instantly to cloudkit therefore if internet is not reachable I have to handle the situation. I had the idea of having a local sqlite db and sort of keep track of connectivity and deal with syncing manually. Here is where 2nd problem comes in in which any inconsistency of the data must be handled by me (e.g. if the user edits the data while offline).
I found YapDatabase library doing the exact things but I feel the learning curve is a little bit steep.
Another idea could be using sqlite db but saving the file in the icloud drive. This way it will be persisted automatically while I have access to the app sqlite. Any change in the db tables will change the file singnature and fire icloud drive sync.
What's the best choice?

iOS, Core Data and iCloud - switching context

I am creating an app where data needs to be displayed right away from the local datastore. I fire off a background thread when the app starts to determine if iCloud is available.
I looked everywhere and can't find the solution to this: when iCloud becomes available, can I change the "options" on the persistentStore to start using iCloud transactions?
I'm not sure what the proper approach is in this situation. Everything I try causes the application to crash.
Originally I had it so the iCloud checking wasn't in a background thread and the app worked fine, but occasionally timed out.
You have not to know when iCloud becomes available. You just work with data but you don't send them directly to iCloud. iOS does it instead you. So only it knows when and how it should send data.
No, you can't change the options on an NSPersistentStore object once it exists. You can only specify the options when adding the persistent store to the NSPersistentStoreCoordinator. The closest you could get to changing options would be to tear down the entire Core Data stack and start over with different options.
That wouldn't help, though, because:
Even if you have detected that iCloud is available (I'm guessing using NSFileManager, either via its ubiquityIdentityToken or by calling URLForUbiquityContainerIdentifier:), your call to addPersistentStoreWithType:configuration:URL:options:error: might still block for a while. If there's new data available in iCloud, it doesn't start downloading until you add the persistent store, and that method doesn't return until the download process is finished. And sometimes, iCloud just makes that method block for a while for no readily apparent reason.
If you let the user make any changes to the data while using non-iCloud options, those changes will not get automatically sent to the cloud later. Core Data only sends changes to iCloud when the data changes while iCloud is active-- which makes it generate a transaction. You'd have to load and re-save any changes the user made, or those changes would never make it to the cloud.
You have, unfortunately, hit on one of the major stumbling points when using Core Data with iCloud. You can't make the full data store available until Core Data finishes communicating with iCloud-- because your call to add the persistent store doesn't return until then. And you can't do anything to speed up that process. This is just one of the headaches you'll run into if you continue trying to use iCloud with Core Data.
Depending on the nature of your data you might be able to use two data stores, one purely local and one synced via iCloud. You could make the purely local data store available while the iCloud one tries to get its act together well enough to be useful. If you stick with one data store though, you're stuck with the delay.

Bootstrapping data at application startup with Simperium

As someone that experienced the pain of iCloud while trying to prototype iCloud enabling one of our CoreData apps, Simperium looks very promising, but I'm interested in seeing how it handles some of the sharp edges.
One issue I came across was how to gracefully handle bootstrapping data when the application starts up. The first time a user launches our app, we will load some default data into our CoreData database. If a user launches the app first on the iPhone and then later on the iPad, they will end up getting the bootstrap data duplicated on both devices because of syncing. With iCloud, the solution was to hook into the iCloud merge process.
How would I handle this with Simperium?
There are at least a couple ways to do this.
You can hardcode the simperiumKey for each seeded object. For example, in a notes app, if every new user gets a welcome note, you can locally create that note with the simperiumKey of welcomeNote. This will ensure that only one welcome note will ever exist in that user's account (on any device). With this approach, there can be some redundant data transfer, so it's best if there's not a large amount of seeded data. On the other hand, this approach is good if you want data to be immediately available to new users even if they're offline when they first launch your app.
With Simperium, you also have the option to use a server process. You can seed new user accounts with data by using a Python or Ruby listener that runs some code when accounts are created. This is a good approach if there's a large amount of data, but has the disadvantage that users need to be online before the seeded data will transfer (and of course the transfer itself will take some time).
There are subtleties with these approaches. With the first approach, using the welcomeNote example, if your user deletes the welcomeNote and subsequently reinstalls your app in the future, the welcomeNote will get resurrected (but never duplicated) because it's being created locally. This is often acceptable. With the second approach, the welcomeNote would be seeded once and only once, so it will never get resurrected even if your app is reinstalled.

iOS web app with offline cache and local storage

I've already managed to program a webapp for personal use I'm really satisfied with. Not being something meant for public usage and distribution, I didn't want to go through the hassle of jailbreaking my device just to be able to run my own application, so I made this seamlessy looking and behaving webapp (and of course I've added it to the other apps saving it as a "Home application")
Since the start time can be a bit slow and I'm constantly pushing my data from and to a remote server, can I force the usage of html5 offline browsing (with a cache manifest) even when I am online? Also, I'm thinking of persisting the data as local storage and from time to time synch it to the server. Since I've never used html5 local storage, how much reliable is it? Can I lose my data?
Is this a viable pattern to quickly create a personal iPhone app? Thanks
Yes, you can force the usage.
so basically you should a very simple checking :
if(localStorage["mycontent"]!==null)
{
// do it offline.
}else
{
// retrieve from server database
}
For your question regarding :
Also, I'm thinking of persisting the data as local storage and from
time to time synch it to the server. Since I've never used html5 local
storage, how much reliable is it? Can I lose my data?
The answer is it depends. If the data is static (or can only be changed by you and not other user ) it's reliable. You also have to take note when a data can be considered expired so localstorage can be filled with refreshed data from the server.
But take note that cleaning history is also remove your data, so only use Localstorage as a cache/mirror of the data in the server.
window.localStorage.setItem('x',y);
window.localStorage.getItem('x';
window.localStorage.removeItem('x');
Lets you store, read and delete persistent data in HTML5. See https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API
But note that on IOS Safari puts this data in the cache folder which on occasions gets expunged. So do plan a server sync and restore of this data if important.
Alternatively use a local SQLite database for a more persistent persistence....

SQLite Persistence throughout app lifecycle on iOS

I've been reading up on SQLite3 included in the iOS firmware which might serve my needs for the app i'm writiung.
What I can't figure out is if it is persistent or goes away like some objects do.
For example if I do sqlite3_open() which appears to be a C function rather than an Objective-C object, if I open this at the start of my application, will it stay persistent until I close it no matter how many views I push/pop all over the place.
Obviously that would depend on where I put it but if I was doing a universal app and had some central functions for loading / saving data which were common to both iPhone/iPad, if, in my didFinishLoading: I put a call to open the SQLite database and then called various exec's of queries, would it remain persistent throughout the lifecycle of the application.
or
Am I better off opening and closing as needed, i'm coming from a PHP background so i'd normally open a database at the start of the script and then run many queries and then finally close it before browser output.
From the 1,000,000th i've learned over the last few months about iOS programming, I think the latter might be the better way as there's possibility of app exit prematurely or it going to background.
I'd just like a second opinion on my thinking please.
I dont know directly, but I think you are right - you only need to open it once at the start of your app.
Looking at sqlitepersistentobjects, an ORM framework for iOS, it only opens the DB when its first used, and never closes it except when there is a problem opening it :)
Single opened sqlite database used throughout the app from different places in your app is fine.
You are using word "persistent" which is confusing. What you mean is "reuse of single connection, for executing different statements in the app, possibly from different threads". Persistence has completely different meaning in context of databases - it means that the requested modification of data has been safely stored to media (disk, flash drive) and the device can even unexpectedly shut down without affecting written data.
It's recommended to keep running sqlite statements from a single, dedicated thread.
It's not recommended to connect to sqlite database from different processes for and executing parallel modifications.
A good alternative solution is to use sqlite async extension which sends all writes to a dedicated, background thread.
You can check out https://github.com/mirek/CoreSQLite3 framework if you want to use custom built (newer version) of sqlite.

Resources