views:

4725

answers:

4

I am writing an iPhone 3.0 application that uses Core Data to persist the model. I'd like the application to be installed with a default dataset. When developing for iPhone < 3.0 I used an SQL script to initialize a database prior to running a build and then deployed the prepared .sqlite file as an application resource. What's the best approach with Core Data.

A conclusion: In the end I wrote a generic XML handler. Element names are mapped to Objective-C class names and property names. PCDATA values within elements were converted into the type declared on the property named by the element. Child elements or property elements were resolved to object instances - and thus through parsing an XML document an object graph was built. I had to get to grips with the Objective-C runtime first though :-)

Example target classes:

@interface Widget : NSObject {
@private
    NSString* name;
    NSSet* sprockets;
}
@property (nonatomic, retain) NSString* name;
@property (nonatomic, retain) NSSet* sprockets;
- (void)addSprocketsObject:(Sprocket*)value;    
@end

@interface Sprocket : NSObject {
@private
    NSString* name;
    NSNumber* canFly;
    NSNumber* wheels;
}
@property (nonatomic, retain) NSString* name;
@property (nonatomic, retain) NSNumber* canFly;
@property (nonatomic, retain) NSNumber* wheels;
@end

Example default data:

<data>
    <Sprocket id="sprocket-1">
        <name>Sprocket1</name>
        <wheels>4</wheels>
    </Sprocket>
    <Widget id="widget-1">
        <name>MyWidget</name>
        <sprockets>
            <Sprocket ref-id="sprocket-1"/>
            <Sprocket id="sprocket-2">
                <name>Sprocket2</name>
                <canFly/>
            </Sprocket>
            <Sprocket id="sprocket-3">
                <name>Sprocket3</name>
            </Sprocket>
        </sprockets>
    </Widget>
</data>
+2  A: 

Two options spring to mind:

  1. Write an importer from some reasonable data format (XML, JSON, etc.) and import that into your Core Data context on first run, then save the context to a persistent store.
  2. If your app only needs one persistent store, you can pre-populate it and deploy the persistent store with your app's resources. If you need multiple persistent stores, all pre-populated with the same default data, option 1 is probably going to be easier, but you could use NSPersistenStoreCoordinator's migratePersistentStore:toURL:options:withType:error: (or the equivalent in iPhone Core Data -- still under NDA) to create the new store from the pre-poplated store for each new store needed.

In my experience the code to implement option 1 is nearly the same code as required to prepopulate a persistent store, so perhaps there's really only one option with two points of view.

Barry Wark
A: 

Can I add a CSV file as a resource to the project and just parse that file and populate the persistent store one-time?

That's what @Barry Wark is suggesting. I haven't tried this yet.
teabot
A: 

Could you show the actual implementation code you used to import this data? I guess I don't know enough to do this and cannot find any example code anywhere else. Thanks!

Howell
+1  A: 

You can use Plist to store the initial data and populate your persistent store on first run. This approach is easier than having to write your own custom XML parser.

Boon