How to use a pre-populated database on a coredata context - iphone

this is my first question here.
Well, I am developing an iPhone application that will use coredata, but the theres not going to be an option to insert data into the database of the app.
I want to know how to pre-populate it's database.
I thought of creating a plist with all the info and make a function to put it all into the coredata database if the database is not set yet...
but I want to know if it is the right way to do so.
Thanks all.

The easiest way is to create a desktop application with the same model (the exact same model even, just link it in). Then have Interface Builder create you a default UI for it and enter the data. Far easier than doing it on a device.
Once you have the data then include the SQLite file in your bundle and since your app is read only as you claimed; point the NSPersistentStoreCoordinator at the file in your app bundle and Bob's your uncle.
Creating an app on the desktop takes about 5 minutes and will save you far more time on the data entry side.

You can pre-create the database file (sqlite file) using your device and put that in the bundle when you distribute it. When you run the app for the first time you can move that from your applications bundle you can move it to the documents directory where core data will read it.
You can also have a function that runs at the start of your applications first run where it reads from your plist and creates the appropriate objects.

Related

Loading a database directly into CoreData

Is it possible to load a database / entity directly into CoreData? The app relies of data, the initial data load being > 100,000 items. On an iPhone 4 it's taking about 15 minutes to complete the insertion, which is an unpleasantly long time.
Is there any way I could:
Load a pre-populated entity into CoreData
Load a pre-populated database (all entities) into CoreData
Something along these lines
to make the insertion of data significantly quicker
Thanks.
Create your database using CoreData and add it to your project bundle, then at first load, copy the database from the bundle to the file system so it will be writable, then open it from there. You may want to mark the database as don't share to iCloud depending on your needs.
Yes it is possible. The 'normal' approach to this is to pre-build the database, include it as a resource, check on startup whether you have a database in the documents folder and, if not, copy it over from the bundle.
I usually run my code to build the database on the simulator, and then go copy it from the sim folder and add to my project resources.
Copying a pre-made Core Data generated sqlite file via the application bundle is a good idea, even though I find it a bit cumbersome. This make most sense if you have a store for static data and one for dynamic data - in most cases it is feasible to copy the static one like this.
But nevertheless, for the record, 15 minutes is ridiculous. I can close to guarantee that you can cut this down to a few seconds.
I have been able to accomplish 500K inserts in less than 30 seconds on a first generation iPad. The most important optimisation techniques are:
disabling the undo manager,
using a background thread with #autoreleasepool,
saving periodically with exactly the right batch size (determine experimentally).

iOS Programming suggestion request REF sqlite/iOS app design

I currently have an iOS app that provides a sqlite DB for the data backend to the app. This data is basically a list of information. Within this app I allow the users to mark records as bookmarked (sets a value in the DB). The problem here is when I post updates to the app via the internet (update through software) for data changes, the new downloaded DB wipes out the old one thereby removing the user customizations.
Any ideas on an easy method to search the current sqlite DB for those changes, store them temporarily, then import the new DB and transfer the changes to the new DB? Could I for instance use a Core Data element at the same time as using the sqlite DB backend? Maybe a key/value pair system?
Any suggestions would be greatly appreciated.
Thanks
-LK
The way I've done it is this:
For your new version, rename your .sqlite file e.g. foo-v2.sqlite. Then, during initialization, check to see if the sqlite file for the old version is there - if so, copy over the necessary info and then delete the old sqlite file.

FInd Out if User Switched off Document and Data From iCloud Account

Once again stuck in iCloud :(. I am using Core Data + iCloud and in my app i want to know if user switched off Document and Data from his account.
Thanks
There is no built-in support for detecting this change, only for detecting if the user has logged out. One common approach is to write a sentinel file to iCloud, separately from Core Data, and then monitor that file to see if it disappears. Details vary but it's usually something like:
Write the file using NSFileManager iCloud calls, and store the file name in user defaults. Each device using the account will have a different file, so including a UUID in the file name is a good idea. You only write this file, you never change it.
Use either NSFilePresenter or NSMetadataQuery to get notified of changes to that file-- like, if it disappears.
If the file disappears, take immediate steps to unload the entire Core Data stack, including every managed object, because they don't have a persistent store backing them up any more.
One sample implementation is in Black Pixel's version of the Core Data "Recipes" demo app. You might need to tweak it to get it to work right in your code.
There are two cases:
The app is not running, or in the background when the account status changes.
The solution here is to store / compare the identity token using NSUserDefaults (or some other storage local to the app). Grab the identity token from NSFileManager and compare it to the cached value each time the app finishes launching or comes back to the foreground.
id token = [[NSFileManager defaultManager] ubiquityIdentityToken];
The app is running when the account changes.
This requires a file presenter to "something" inside the container. The best solution is to use a file that is not synced.
Implement -accommodatePresentedItemDeletionWithCompletionHandler: to spawn a thread (dispatch_async works great) and do your cleanup work.

on-the-device database for my iphone app

I want to have on-the-device database for my iphone app. It concerns with the data, which comes from dictionary consisting of 200.000 things and their definitions. It is only related with text-type data as appeared. My questions:
1- Does SQLite hold all of these data?
2- When the client downloaded my app, he/she will also have the db in his/her device. Does app store allow me to update my app's db and upload my new release? (i don't know these issues well by the way)
3- And can any client, who downloaded my app, hack and obtain my database? Is there any prevention methods? Is SQLite resilient enough against these?
1- Does SQLite hold all of these data?
Yes, SQLite can cope with this amount of data.
2- When the client downloaded my app,
he/she will also have the db in
his/her device. Does app store allow
me to update my app's db and upload my
new release? (i don't know these
issues well by the way)
The general approach is to store the SQLite database in your application bundle and then copy the database into the application's document directory on the device when the application is first run. On subsequent updates to your applciation, you should check if the database within the document directory is the same version and update it if necessary. See the existing Run NSBundle from the documents folder question/answer for more information on this.
3- And can any client, who downloaded
my app, hack and obtain my database?
Is there any prevention methods? Is
SQLite resilient enough against these?
It's fairly trivial to open up an app (the deployment package is just a zip file after all), so yes, it will be possible to obtain access to your database data. Unfortunately there's no easy way around this that I'm aware of. (You could I suppose download the data from a server when you first run you app, but it'll still be accessible on a jailbroken device.)
Sometimes, you just have to bite the bullet and accept the fact that your data is going to be ripped off.
1) sqllite can definitely hold that amount of data.
2) You can put up an option of refreshing the database in your app. That can be used to sync the local db with the server copy. Updated db can also be added with the new version of the app.
3) You can encrypt your local db using SQLCipher for protecting your application db against hacks.

Core Data - Add Static / Lookup Data

I am creating an application, and am using Core Data as my backend data source.
I am wondering how I can manually add entries into a Core Data Entity which can be used to hold static data which will never change throughout the applications lifetime.
There are many solutions to this issue. First, for data entry, you can create a trivial desktop application in a couple of minutes that will let you do the data input. Since the underlying sqlite file is the same, you can then copy the file to your project.
As for accessing it, depends on your data structure. If you have entities that are both static and editable (such as a look up list that can be added to), then I suggest carrying the sqlite file in your bundle and on first launch copy it to the documents directory.
If the tables are NEVER writable then you can leave the static data in your bundle and create a second store in the documents directory that is writable. You can then bundle the two together on creation of your Core Data stack and the rest of your application will treat them as if they are a single database/object graph. The only issue with this is that you cannot have relationships across files.
I have never tried this, however I think you can populate core data with an example program which you run in the simulator which populates the database with the data.
Then you can get .sqlite database out of the simulator and into Xcode resource folder.
Every time your app starts, even first run the database will contain the objects you first populated it with in the example program.