开发者

How do I create second target in my project to create a pre-populated database for iOS

开发者 https://www.devze.com 2023-03-28 23:23 出处:网络
I currently have an iOS app that can \'bootstrap\' it\'s database from a bunch of pList files (which I use during development when there are db changes) or copy a pre-existing database for the first r

I currently have an iOS app that can 'bootstrap' it's database from a bunch of pList files (which I use during development when there are db changes) or copy a pre-existing database for the first run on a device (I use the database that was created in the simulator).

This is getting messy: I have to flip flags to decide whether I'm bootstrapping or not, I don't want to distribute a 'bootstrap' version by accident, and I don't want to distribute the plists either (then the target device would have 3 copies of the data: the bundled db, the plists, and the writeable copy of the db).

What I would like to do is create a separate desktop app that uses the same object model. The plists would be used by the desktop app, which I would ru开发者_开发知识库n to generate the db (or maybe even provide a GUI for DB tweaks!). The iPhone and desktop app would share the same data model. And the desktop app would write to the db that's bundled with the iOS app, so I don't have to remember to copy from the simulator.

So far, I have been able to find posts that say that this would be trivial to do... but a tutorial or tips would be helpful.


Sasha,

I made a new target in my existing project and was able to create my bootstrapped Core Data DB. It wasn't hard at all. You reuse most of your existing code.

Andrew


You have many options. You can create a side-by-side application whose sole responsibility is to pre-populate the DB in your main app. Or you can use a script to populate the DB file directly. I am including a link to a nice tutorial that describes the latter approach.

http://www.raywenderlich.com/980/core-data-tutorial-how-to-preloadimport-existing-data


The way I've seen this problem dealt with in projects that I've worked on is simple. Make two targets, and configure each one with the appropriate flags. You'll have your "flag flipping", but won't be quite as complicated and you'll be able to easily tell which one you are building.


From your question it sounds as if you can create the Core Data Persistent Store on the desktop. (The caveat here is to ensure you are using a shared Core Data Model.)

Given that, you should bundle the DB as an application resource and copy it into place if it is not found at application startup.

Something like this should do you:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    

    if (![self persistentStoreExists]) { // First run.
        [self copyPersistentStoreFromBundleResources];
    }

    // ... continue here.

}

#pragma mark -
#pragma mark First Run Core Data Import 

- (BOOL)persistentStoreExists
{
    NSString *storePath = [[[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"MyApp.sqlite" ] path]; 
    NSFileManager *fileManager = [NSFileManager defaultManager];

    return [fileManager fileExistsAtPath:storePath];
}

- (void)copyPersistentStoreFromBundleResources
{
    NSLog(@"Installing default DB from bundle.");

    NSString *storePath = [[[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"MyApp.sqlite" ] path];

    NSString *defaultStorePath = [[NSBundle mainBundle] 
                                  pathForResource:@"MyApp" ofType:@"sqlite"];

    if (defaultStorePath == nil) {
        NSLog(@"Error finding default store");
        return;
    } else {
        BOOL copiedDefaultStore = [[NSFileManager defaultManager]
                                   copyItemAtPath:defaultStorePath
                                   toPath:storePath
                                   error:nil];
        if (! copiedDefaultStore) {
            NSLog(@"Error copying default store");
            return;
        }
    }
}

#pragma mark -
#pragma mark Application's Documents directory

/**
 Returns the URL to the application's Documents directory.
 */
- (NSURL *)applicationDocumentsDirectory {
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
}
0

精彩评论

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