読者です 読者をやめる 読者になる 読者になる

ほげほげ(仮)

仮死状態

MagicalRecordでSQLite初期データをコピーする

iOS Objective-C

MagicalRecordを使っていて、SQLiteファイルをコピーする方法です。

最初は初回起動時にJSON等のテキストからSQLiteのデータを普通に作ってたのですが、データ量が多いとすごく時間かかるので、最初からSQLiteファイルを作っておいてコピーする方法にしました。

環境

  • iOS 7
  • MagicalRecord 2.2

初期データ

SQLiteの初期データは事前に作ります。作り方は色々あるかと思いますが、MagicalRecordを介して作っておいたほうが無難かと。

MagicalRecordから作成したファイルは~/Library/Application Support/iPhone Simulator/<シミュレータバージョン>/Applications/<アプリ>/Library/Application Supportにできると思います。

プロジェクトへ追加

初期データをXcodeのプロジェクトへ追加します。

その際ですが、xxx.sqlite, xxx.sqlite-shm, xxx.sqlite-walの3つのファイルをプロジェクトへ追加する必要があります。

コピー処理

下記をMagicalRecordの初期化処理[MagicalRecord setupCoreDataStackWithStoreNamed:@"xxx.sqlite"];より前で実行します。

// MagicalRecordが使用するロケーション取得
NSURL *storeSQLiteURL = [NSPersistentStore MR_urlForStoreName:@"xxx.sqlite"];

if (![[NSFileManager defaultManager] fileExistsAtPath:[storeSQLiteURL path]]) {
    // 未作成の場合にSQLite初期データをコピーする

    NSURL *pathToStore = [storeSQLiteURL URLByDeletingLastPathComponent];
    NSError *error = nil;

    // Application Supportのディレクトリ作成
    if (![[NSFileManager defaultManager] createDirectoryAtPath:[pathToStore path] withIntermediateDirectories:YES attributes:nil error:&error]) {
        DDLogError(@"ディレクトリ作成失敗: %@",error);
    };

    NSURL *storeShmURL = [pathToStore URLByAppendingPathComponent:@"xxx.sqlite-shm"];
    NSURL *storeWalURL = [pathToStore URLByAppendingPathComponent:@"xxx.sqlite-wal"];

    NSURL *preloadSQLiteURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"xxx" ofType:@"sqlite"]];
    NSURL *preloadShmURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"xxx" ofType:@"sqlite-shm"]];
    NSURL *preloadWalURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"xxx" ofType:@"sqlite-wal"]];

    // 各ファイルをコピー
    if (![[NSFileManager defaultManager] copyItemAtURL:preloadSQLiteURL toURL:storeSQLiteURL error:&error]) {
        DDLogError(@"sqliteコピー失敗: %@", error);
    }
    if (![[NSFileManager defaultManager] copyItemAtURL:preloadShmURL toURL:storeShmURL error:&error]) {
        DDLogError(@"sqlite-shmコピー失敗: %@", error);
    }
    if (![[NSFileManager defaultManager] copyItemAtURL:preloadWalURL toURL:storeWalURL error:&error]) {
        DDLogError(@"sqlite-walコピー失敗: %@", error);
    }
}

参考