2009-11-19 51 views
6

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

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

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

回答

3

假设你使用的CoreData与SQLite的支持,那么绝对。最直接的选择是让应用程序为您生成模式,然后使用该空白/外壳数据库,运行您的xml-to-sql迁移工具。你只需要更新你的工具来说明CoreData为xcdm生成的结构。

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

这可能是一个偏好问题。

+1

通过应用程序,你的意思是让Xcode生成模式?还是模式只能在运行时建立? – 2009-11-21 00:04:58

+0

我不是100%确定。我想说它是在运行时生成的(我相信CoreData init的一部分是为了在需要时使数据存储保持最新状态),但是您需要仔细检查。 – 2009-11-21 00:38:21

+0

Xcode不会生成模式。这是一个运行时操作。 – 2009-11-21 03:42:30

2

我不相信Core Data本身就提供了这种类型的功能。如果我在你身边,我会写一个小工具来完成XML解析,并根据需要从数据创建核心数据模型并保存它。然后,只需将核心数据生成的sqlite数据库移动到您的真实项目。

然后或许编写一些代码,将该默认数据库复制到iPhone上的适当位置(如果数据库尚不存在)。如果您将自己置于不良状态,那么您也可以轻松恢复为“干净”数据,因为您可以删除数据库文件并重新运行该应用程序。

+0

其实我已经做了,就像你所描述的,但不是在两个步骤做,我做一个。我在iPhone中创建需要的.sql存储。但是,在将应用程序提交到应用程序商店的时候,这种方法不会导致问题吗?你会如何纠正这个问题? – Stunner 2011-01-22 02:43:30

+0

这为什么会导致问题?我不认为在您的应用中包含种子数据违反了App Store准则。 – 2011-01-22 17:17:13

2

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

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

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

这是一个有效的解决方案。不过,我更喜欢做这种“脱机”的解析,所以应用程序只能看到一个SQLite数据库文件。 – 2009-11-21 00:03:24

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; 
} 
+0

Ey谢谢分享!不过,我在确定MOM路径时遇到了一些麻烦。请参阅http://stackoverflow.com/questions/4600312/how-to-get-path-of-momd-file-in-core-data谢谢! – Stunner 2011-01-05 05:38:01

相关问题