开发者

Core Data Store included in App Bundle

I can't find a clear description of these steps in Apple docs...

  1. I have a xcdatamodeld in my xcode project
  2. At launch time, my app parses a XML (project resource) to fill the Core Data Store (SQLLite)
  3. During lifetime of my app, I add, remove, update data of that Store

Now, I want to stop doing that heavy XML parsing process on device and directly include a开发者_如何转开发 Store containing the required data.

I have some questions regarding this :

  • Can I fill a store with a OS X app and then include this store in my XCode-iOs project ?
  • My store does not appear in Xcode. In fact it is created at run time. How can I add a store in the project and link it to my xcdatamodeld ?
  • I have read that doing so will prevent my store from being writable... I guess I have to copy it in the right place at launch time (the Core Data utility Tutorial is a great help for that). Am I right ?

Thanks for your hints. URL or other SO questions would be really appreciate !

Kheraud


You can include the store file (sqlite db most of the time) in your app. Then in your app delegate edit the persistentStoreCoordinator getter merhod :

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {

    if (persistentStoreCoordinator_ != nil) {
        return persistentStoreCoordinator_;
    }

    NSString *storePath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"CoreDataStore.sqlite"];

    // Check if the store exists in. 
    if (![[NSFileManager defaultManager] fileExistsAtPath:storePath]) {
        // copy the payload to the store location.
        NSString *bundleStore = [[NSBundle mainBundle] pathForResource:@"YourPayload" ofType:@"sqlite"];

        NSError *error = nil;
        [[NSFileManager defaultManager] copyItemAtPath:bundleStore toPath:storePath error:&error];

        if (error){
            NSLog(@"Error copying payload: %@", error);
        }
    }

    NSError *error = nil;
    NSURL *storeURL = [NSURL fileURLWithPath:storePath];
    persistentStoreCoordinator_ = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    if (![persistentStoreCoordinator_ addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }    

    return persistentStoreCoordinator_;
}


  1. Write a utility app using the data model and classes for the app. Use the utility app to generate a persistent store from the data provided by the XML.
  2. Add the store file to the app bundle like any other resource
  3. Pick a location in the app directory where you want the active store to reside e.g. the Library directory.
  4. Upon launch have the app check if the store is present in directory. If it isn't, the app should copy the store from the app bundle to the directory using standard NSFileManger methods just like any other file. (Usually, you only need to do this the first time the store is created. )

That's all there really is to it.


What you're currently doing (populating at first launch) is the "recommended" way of populating a Core Data store. Although its a bit hackish, you could however seed the on-device database as follows:

  1. Launch your app in the simulator
  2. Do whatever you need to do for the simulator app to populate the Core Data store
  3. Stop the simulator app
  4. Navigate to the simulated Documents folder (something like ~/Library/Application Support/iPhone Simulator/4.3/Applications/335567A0-760D-48AF-BC05-7F0D9BD085B6/<app-name>.app/)
  5. Find the sqlite database (it has the name you gave it when initializing Core Data)
  6. Copy this database to your project, and add it to be copied as a resource
  7. Add some code to your application:didFinishLaunchingWithOptions: method so that on first launch, it copies the database from the read-only resources directory to the app's documents directory. Of course you need to do this before initializing Core Data.

Depending on exactly what you're storing in your database, you may however discover big- vs. little-endianness issues, or other incompatibilities. To make the approach a bit safer, you could dump the simulator database (splite3 databasefile .dump >dumpfile) on your Mac, then include the dumpfile in your project (as above), and slurp the dump in your app on first launch (reading it line-by-line, and handing the sql statements to the sqlite API).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜