1

I have an iPhone app that uses CoreData.

I want to add a pre-populated SQLite database to it. The database has 1 table (geographic locations, about 50K of them).. cities.sql I am a bit puzzled what would be the best way to add this database?

I saw several approaches (such as locating the app folder in /Users/user/Library/... ) but my external database does not really have the same structure as apps database (no "User" table etc..).

I just want to treat this cities.sqlite as some data source.. I don't mind merging it with the apps appname.sqlite if necessary...

I am also using RestKit to manage the CoreData / API integration.

Question - how do I add this cities.sqlite to the app so I can ship the app with the pre-populated data from that database ?

asked Feb 21, 2013 at 20:49
4
  • Does the app is already published or not? Commented Feb 21, 2013 at 20:50
  • no it is not, in development Commented Feb 21, 2013 at 20:51
  • Is your SQLite database in Core Data format? I mean, if it was created by Core Data, so it can understand and open it correctly. Commented Feb 21, 2013 at 21:38
  • no it was not created by CoreData - it was created by SQLite manager Commented Feb 21, 2013 at 21:47

2 Answers 2

3

Ok,

my approach to create a pre-populated db is to create a dummy app that has the goal to only populate the db you want to create. This let me to do some testing on the db without using the real app. Obviously, models should be the same.

Then, you can put it to the main bundle of your real app. Once executed, the app will check if the db exists in your document folder (for example), if not, it will copy the db from the bundle to the document folder.

NSString *storePath = [[self applicationDocumentsDirectory] 
 stringByAppendingPathComponent: @"yourStore.sqlite"];
NSURL *storeUrl = [NSURL fileURLWithPath:storePath];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:storePath]) {
 NSString *defaultStorePath = [[NSBundle mainBundle] 
 pathForResource:@"yourStore" ofType:@"sqlite"];
 if (defaultStorePath) {
 [fileManager copyItemAtPath:defaultStorePath toPath:storePath error:NULL];
 }
}

In Core Data Import, you can find what I mean (for the second part, but you are free to follow also the approach to populate the db).

Hope that helps.

Edit

I'll try to explain better.

You create a dummy project.

Here you can use the model (with its entities) you created in the main app. Just copy it i your dummy project. Create some code to populate the sql store through NSManagedObjectContext stuff. The result will consist in a sql store already populated. You don't need to touch any sql store (only through Core Data). Move to the application folder directory into the App Simulator, copy the store and put it in your main application bundle.

answered Feb 21, 2013 at 21:01
Sign up to request clarification or add additional context in comments.

4 Comments

you say models should be the same - if my main db has "users", "venues", "cities" for example and I just want to import "cities" - can I just use this approach to import the cities.sqlite which has 1 table ("cities") but with a structure identical to the main app?
sorry, I cannot understand what you're asking. Could you explain better your goal? Thanks
@Stpn You are talking about tables or entities? Are you working with plain sqlite file or with sqlite created by Core Data?
this actually worked in the end. I guess I will go with this solution. Thanks.
3

EDIT: If you are working with plain SQLite database, you will need to migrate the data to CoreData-friendly persistent store. To do this you can use sqlite library to read the data. You can do this in app directly, or you write some ulitity app for this. After you get the SQLite Core Data persistent store, follow my original post:


With Core Data you can have multiple SQLite stores combined into one context. Just add two persistent stores to your NSPersistentStoreCoordinator.

[coordinator addPersistentStoreWithType:NSSQLiteStoreType
 configuration:nil
 URL:mainSQLiteURL // URL for your main DB
 options:nil
 error:nil];
[coordinator addPersistentStoreWithType:NSSQLiteStoreType
 configuration:nil
 URL:citiesSQLiteURL // URL for the additional DB
 options:nil
 error:nil];

After this, when you create NSFetchRequest with entity City (I don't know your entity name) it will return cities from both SQLite files.

In case you want to just search one of the stores, you can set -setAffectedStores: of your fetch request. Also, when you insert new City object, you will need to specify the persistent store by calling -assignObject:toPersistentStore: on your context. Otherwise it will get confused about where to save the new city.

Or just merge those two stores to a single file.

answered Feb 21, 2013 at 21:55

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.