2009-11-19 39 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

相關問題