views:

983

answers:

5

Hi, I'm creating an iPhone App and am wondering whether Core Data is better for readonly data than a SQLite database. It feels like the SQLite DB is the better choice, is that right? Can I even pre-fill the Core Data storage?

Basically, I need like 3 tables with a bunch (up to 3000) of entities each. I then want to list the data in TableViews, search on it or load things for other purposes.

Should or can I use Core Data in this case?

A: 

Core Data uses SQLite (among other options), so your question is somewhat flawed.

Azeem.Butt
I wouldn't consider it a flawed question. While CoreData uses SQLite for *underlying* storage, you don't have any interface to SQLite itself. Instead the power of CoreData derives from its classes and methods. For example, `NSFetchedResultsController` when used with a `UITableView` will help efficiently read data from disk as it is needed, and manage memory accordingly. You're essentially left to do this on your own if you use straight SQLite.
jbrennan
Where does the SQLite API go when you use Core Data? As far as I can tell, it's still there.
Azeem.Butt
I don't care whether I can access both at once (probably a bad idea when having Core Data manage your objects). I want to use one and need to know which one is best.
Christian
+2  A: 

You definitely can ship a pre-filled Core Data store in your app, just as you could a pre-filled SQLite database, or a big plist with all of your data (though that sounds like a bad fit for this case), or whatever.

Core Data is nice because it's all native Cocoa, it handles all of the loading from the DB into native objects, it's been ruthlessly optimized, and so on. But there's also a lot of code there to do stuff that you don't care about: handling revisions, saving changes, undo and redo support, etc. So there's not really an obviously right answer one way or the other.

A lot will depend on your level of comfort with both Core Data and the alternatives. Are you happy dealing with the SQLite API (or one of the many Cocoa wrappers) to get your data? If so, then that might be simpler. If having Core Data do the ORM for you would be a big win, then go that way. On the other hand, complex queries with Core Data use the predicate APIs, which might be more complex than using bare SQL with SQLite. That kind of thing.

Sixten Otto
I added the information that it can be up to 3000 records in one of the tables. If I easily could decide on my own, I won't have to ask here. But knowing that there are no big disadvantages helps.
Christian
+2  A: 

Depending on how relational they are, you might be better off reading the read-only data from a plist. Plist's are easy to load/save (they turn into NSDictionaries) and are probably easier to edit

coneybeare
Ah, haven't thought of that. They are relational. It's like "a station belongs to a route that belongs to a means of transportation". That's not optimal for plists, right?
Christian
Depends. Is it strictly hierarchical, or are there many-to-many relationships? A plist does the former just fine, but the latter is more difficult.
Sixten Otto
Yeah, there's a many-to-many relationship. So I better don't go with plists. Thanks a lot!
Christian
+8  A: 

If you will be displaying your read-only data in a table view, there can be significant advantages to using Core Data over SQLite simply due to NSFetchedResultsController. This convenience class makes it extremely easy to display database elements in a table view, and it can handle batched fetching for you. The batched fetching lets you load only the information you need on screen right then, dramatically improving loading time and memory usage for all but the smallest data sets.

I use Core Data for read-only information that I ship in my application's bundle for this reason, along with the fact that I can share a data model with the writable database stored in the user's application data. My recommendation is to go with Core Data unless you absolutely need to target iPhone OS 2.x devices.

Brad Larson
+4  A: 

Here's a simple way to preload the Core Data store using plists.

Make a property list containing an array of dictionaries. Make the keys of each dictionary correspond to the keys of your managed object.

alt text

Then, call this method the first time the app launches:

- (void)loadDataFromPropertyList {
    NSString *path = [[NSBundle mainBundle] pathForResource:@"someFile" ofType:@"plist"];
    NSArray *items = [NSArray arrayWithContentsOfFile:path];

    NSManagedObjectContext *ctx = self.managedObjectContext;

    for (NSDictionary *dict in items) {
        NSManagedObject *m = [NSEntityDescription insertNewObjectForEntityForName:@"TheNameOfYourEntity" inManagedObjectContext:ctx];
        [m setValuesForKeysWithDictionary:dict];
    }

    NSError *err = nil;
    [ctx save:&err];

    if (err != nil) {
        NSLog(@"error saving managed object context: %@", err);
    }
}

Call loadDataFromPropertyList the first time the app launches by including the following code in the implementation of application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions:

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];  
if (![defaults objectForKey:@"firstRun"])
{
    [defaults setObject:[NSDate date] forKey:@"firstRun"];
    [[NSUserDefaults standardUserDefaults] synchronize];
    [self loadDataFromPropertyList];
}
Rose Perrone