CoreData データベースにマスタデータを取り込む方法

iOS アプリで SQLite のマスタデータをデータベースに用意することに少し苦労したので、メモしておく。

iOS アプリで生成した SQLite データベースのテーブル構成を SQLite database browser で確認した。

・CoreData のテーブルには、テーブル名に"Z"が付加されている
・テーブル カラムにも"Z_PK", "Z_ENT", "Z_OPT" などの制御カラム(?)が追加されている

上記制御カラムの生成ルールがよくわからなかったので、CoreData データベースへのデータ追加は CoreData プログラムコードで行うこととした。
(他にいい方法はないのものか?)

1. 自作のCSVデータ取り込みアプリ(CoreData)でデータをインポート

CSVデータ取り込みアプリの .xcdatamodel にマスタテーブルを定義する
マスタテーブルへデータを取り込めるように改変する
マスタ データを取り込む

2. アプリで利用するSQLiteデータベースへデータをコピー

1
2
3
4
5
6
7
8
$ sqlite3 アプリのデータベース ファイル名.sqlite
sqlite> attach database 'マスタを保持したデータベース ファイル名.sqlite' as old;
sqlite> .database
sqlite> begin;
sqlite> insert into main.テーブル名('Z_ENT', 'Z_OPT', …カラム名) select Z_ENT, Z_OPT, …カラム名 from old.テーブル名; 
注意点: Z_PK などのプライマリキーは指定できない
sqlite> commit;
sqlite> .exit

3. NSBundle からデータベースをコピー

マスタデータを含むデータベースを xcode プロジェクトに追加しておき、アプリ起動時に以下のコードでコピーする。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#pragma mark - Application's documents directory
 
// アプリのドキュメント ディレクトリ パスを返す
- (NSString *)applicationDocumentsDirectory
{    
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
    return basePath;
}
 
- (void)setupSqliteDb
{
    // SQLiteデータベース を保存するパスを取得する
    NSString *storePath = [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"BikeMaintenance.sqlite"];
    NSFileManager *fileManager = [NSFileManager defaultManager];
 
    // SQLiteデータベースが存在しない場合、作成する
    if (![fileManager fileExistsAtPath:storePath]) {
        NSString *defaultStorePath = [[NSBundle mainBundle] pathForResource:@"BikeMaintenance" ofType:@"sqlite"];
        if (defaultStorePath) {
            [fileManager copyItemAtPath:defaultStorePath toPath:storePath error:NULL];
        }
    }
}