iOS

[iOS SDK] Core Data で、デフォルトデータを読み込ませる方法

CoreData で、用意したデフォルトデータを初回起動時に読み込ませたかったので、その方法をまとめてみました。

環境:Xcode 4.2.1, iPhone 5.0 Simulator

デフォルトデータの作成

デフォルトデータを作成するために、「Master-Detail Application」で新規プロジェクトを作成します(「Use Core Data」にチェックが入っていることを確認します)。

このサンプルプログラムは、右上のプラスボタンを押すたびに、現在の日時を格納します。ここでは、iOS Simulator で実行して、プラスボタンを連打してデフォルトデータを作成します。

デフォルトデータの所在

作成したデータは、以下のアドレスにあります。

/Users/ユーザ名/Library/Application Support/iPhone Simulator/バージョン名/Applications/アプリ名/Documents/アプリ名.sqlite

これをプロジェクトの「Supporting Files」などに入れておきます。ドラッグ&ドロップして入れた場合は、「Copy items into destination group’s folder」、「Add to targets」にチェックを入れて、ファイルをコピーしておきます。

データをコピーするようにコードを修正

AppDelegate.m の persistentStoreCoordinator() というメソッドで、データをロードしていますので、ここを変えてあげます。

変更前。コメントは省いています。

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (__persistentStoreCoordinator != nil)
    {
        return __persistentStoreCoordinator;
    }
    
    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Hoge.sqlite"];
    
    NSError *error = nil;
    __persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error])
    {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }    
    
    return __persistentStoreCoordinator;
}

一旦、iOS Simulator からアプリを削除して、用意したデータを読み込ませるように書き換えます。

変更後。

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
    if (__persistentStoreCoordinator != nil)
    {
        return __persistentStoreCoordinator;
    }
        
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    NSString *writableDBPath = [documentsDirectory stringByAppendingPathComponent:@"Hoge.sqlite"];
    
    NSString *storePath = [[NSBundle mainBundle] pathForResource:@"Hoge" ofType:@"sqlite"];
    
    
    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Hoge.sqlite"]; 
    
    NSLog(@"store URL %@", storeURL);
    
    NSFileManager *fileManager = [NSFileManager defaultManager];
    if (![fileManager fileExistsAtPath:writableDBPath]) {
        NSString *defaultStorePath = [[NSBundle mainBundle] pathForResource:@"Hoge" ofType:@"sqlite"];
                
        if (defaultStorePath) {
            [fileManager copyItemAtPath:defaultStorePath toPath:writableDBPath error:NULL];
            NSLog(@"storePath= %@", storePath);
        }
    }    
    
    NSError *error = nil;
    __persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) {
        
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }    
    
    return __persistentStoreCoordinator;
}

これで起動すると、アプリ起動時にデフォルトデータが読み込まれていると思います。

参考