简体   繁体   English

如何在我的项目中创建第二个目标来为 iOS 创建预填充的数据库

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

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).我目前有一个 iOS 应用程序,它可以从一堆 pList 文件中“引导”它的数据库(我在开发期间有数据库更改时使用)或复制预先存在的数据库以在设备上首次运行(我使用数据库在模拟器中创建)。

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).这越来越混乱:我必须翻转标志来决定我是否正在引导,我不想意外分发“引导”版本,我也不想分发 plist(然后是目标设备将有 3 个数据副本:捆绑的数据库、plist 和数据库的可写副本)。

What I would like to do is create a separate desktop app that uses the same object model.我想做的是创建一个单独的桌面应用程序,它使用相同的 object model。 The plists would be used by the desktop app, which I would run to generate the db (or maybe even provide a GUI for DB tweaks.).这些 plist 将由桌面应用程序使用,我将运行它来生成数据库(或者甚至可能为数据库调整提供 GUI。)。 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. iPhone 和桌面应用程序将共享相同的数据 model,桌面应用程序将写入与 iOS 应用程序捆绑的数据库。 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 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.从您的问题来看,您似乎可以在桌面上创建 Core Data Persistent Store。 (The caveat here is to ensure you are using a shared Core Data Model.) (这里需要注意的是确保您使用的是共享的核心数据 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.鉴于此,您应该将 DB 捆绑为应用程序资源,如果在应用程序启动时找不到它,则将其复制到位。

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];
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM