将现有数据预加载到基于Core Data的iPhone应用程序中?

时间:2009-11-19 23:27:41

标签: iphone core-data

在之前的项目中,我为2.2.x构建了一个使用SQLite的iPhone应用程序。它具有需要预先加载到构建中的现有数据(以XML格式)。所以我编写了一个小工具,它使用libxml2来解析XML,然后写出一个SQLite数据库,然后将其作为资源直接包含在构建中。这很好。

我将在几周内为不同的客户启动一个新项目,该项目的参数大致相同。我将需要一些现有数据来解析并转储到应用程序将显示的文件中。但是,这次我想使用Core Data并为3.x设备构建应用程序。但是,我没有对Core Data使用的底层数据库模式的显式和直接访问。 (这是核心数据的重点)

如何将现有数据预加载到基于Core Data的iPhone应用程序中?我可以自动化该过程(类似于我上面用SQLite所做的)吗?

4 个答案:

答案 0 :(得分:10)

我参加这个派对有点晚了,但我正在为GroceryList做类似的事情。我有数据存储在我的CoreData sqlite商店中需要的plist文件中。我编写了一个命令行基础工具,它在我的Mac上运行,解析plist文件,然后使用我的Core Data对象模型创建一个sqlite存储。我运行此命令行工具作为我的构建的一部分(对于一些构建配置),以便我可以随意重新生成数据。要在xcode中创建此类工具,请选择文件 - >新项目 - > Mac OS X - >命令行工具,然后从“类型”菜单中选择“核心数据”。这是一些示例代码:

#import <objc/objc-auto.h>

int main (int argc, const char * argv[]) {

    objc_startCollectorThread();

    //You may not know this, but NSUserDefaults can be used to parse command line arguments!
    //in this case, the arguments are passed in like this:
    // -fullMomPath /hd/some/path/file.mom -fullStorePath /hd/some/path/file.sql
    //by passing in the storePath, the calling script knows where the sqlite file will be and can copy it to the resulting application bundle
    NSUserDefaults *args = [NSUserDefaults standardUserDefaults];   
    NSString *momPath = [args stringForKey:@"fullMomPath"];
    NSString *storePath = [args stringForKey:@"fullStorePath"];

    // Create the managed object context
    NSManagedObjectContext *context = managedObjectContext(momPath, storePath);


    //build and save your NSManagedObjects here
    //in my case, i parse some plist files and create GroceryList type stuff, but whatever you do is your business.

    return 0;
}

NSManagedObjectModel *managedObjectModel(NSString* momPath) {

    static NSManagedObjectModel *model = nil;

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

    NSURL *modelURL = [NSURL fileURLWithPath:momPath];
    model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

    return model;
}



NSManagedObjectContext *managedObjectContext(NSString* momPath, NSString* storePath) {

    static NSManagedObjectContext *context = nil;
    if (context != nil) {
        return context;
    }

    context = [[NSManagedObjectContext alloc] init];

    NSPersistentStoreCoordinator *coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: managedObjectModel(momPath)];
    [context setPersistentStoreCoordinator: coordinator];

    NSString *STORE_TYPE = NSSQLiteStoreType;

    NSURL *url = [NSURL fileURLWithPath:storePath];

    NSError *error;
    NSPersistentStore *newStore = [coordinator addPersistentStoreWithType:STORE_TYPE configuration:nil URL:url options:nil error:&error];

    if (newStore == nil) {
        NSLog(@"Store Configuration Failure\n%@",
              ([error localizedDescription] != nil) ?
              [error localizedDescription] : @"Unknown Error");
    }

    return context;
}

答案 1 :(得分:3)

假设你正在使用带有SQLite支持的CoreData,那绝对是。最直接的选择是让应用程序为您生成模式,然后使用该空/ shell DB,运行xml-to-sql迁移工具。您只需更新工具即可考虑CoreData从xcdm为您生成的结构。

或者,您可以使用您的工具编写包中包含的sqlite数据库,然后在启动时运行时,从sqlite数据库中读取数据,将其吐入CoreData,然后继续。这将使用您的sqlite DB作为“预加载数据”的容器,以及CoreData数据存储中的所有进一步数据交互。

这可能是一个偏好问题。

答案 2 :(得分:2)

我不相信Core Data本身就提供了这种类型的功能。如果我在你的位置,我会编写一个小工具来完成XML解析,并根据该数据创建核心数据模型所需的一切并坚持下去。然后,只需将sqlite数据库Core Data生成移动到您的真实项目中。

然后可能编写一些代码,将默认数据库复制到iPhone上的正确位置(如果数据库尚不存在)。如果您陷入糟糕状态,那么这也可以让您轻松恢复“干净”数据,因为您可以删除数据库文件并重新运行应用程序。

答案 3 :(得分:2)

您可以采用类似的方法。最简单的方法是设置核心数据托管上下文,然后读入XML文件,在解析XML文件时创建托管对象。

    NSManagedObjet *managedObject = [[NSEntityDescription insertNewObjectForEntityForName:@"DataTypeName"
                                                                   inManagedObjectContext:managedContext] retain];

    [managedObject setValue:@"some data" forKey:@"keyName"];
    /* ... */