しめ鯖日記

swift, iPhoneアプリ開発, ruby on rails等のTipsや入門記事書いてます

Realm Swiftのマイグレーションを試してみた

以前RealmのCrud処理を試したのでその続きを書いてみます。
今回はマイグレーションの方法を調べてみます。

llcc.hatenablog.com

テーブルとデータの作成

まずは下のようにModelを作ってデータを作成します。

import RealmSwift

class User: Object {
    dynamic var id = 0
    dynamic var name = ""
    
    override static func primaryKey() -> String? {
        return "id"
    }
}
import RealmSwift

let realm = try! Realm()
let user = User()
user.id = 0
user.name = "Name1"
try! realm.write {
    realm.add(user)
}

下のようにすると先ほど作成したデータを取得できます。

import RealmSwift

realm.objects(User)[0]

テーブル構造を変更してみる

次はテーブルの構造を修正してみます。
下のようにvalueというカラムを追加しました。

class User: Object {
    dynamic var id = 0
    dynamic var name = ""
    dynamic var value = ""
    
    override static func primaryKey() -> String? {
        return "id"
    }
}

この状態でデータを取得しようとすると下のようなエラーが発生します。

import RealmSwift

realm.objects(User)[0]
Terminating app due to uncaught exception 'RLMException', reason: 'Migration is required for object type 'User' due to the following errors:
- Property 'value' has been added to latest object model.'

マイグレーションする

この書き方は古いものなので次項の書き方を参考にして下さい

上の修正が問題なく動くようにマイグレーションを実装します。
下の公式ドキュメントを参考にしました。

Swift Docs - Realm is a mobile database: a replacement for SQLite & Core Data

下のようにすればマイグレーションが走ります。
新しいカラムへの値のセットも可能です。
今回は新しく追加したvalueカラムにnameの値を入れます。

import RealmSwift

setSchemaVersion(1, realmPath: Realm.defaultPath) { migration, oldSchemaVersion in
    if oldSchemaVersion < 1 {
        migration.enumerate(User.className()) { oldObject, newObject in
            let name = oldObject!["name"] as! String
            newObject!["value"] = name
        }
    }
}

realm.objects(User)[0]

今後更にカラムの追加等をする場合はsetSchemaVersionの第一引数の値を増やしていきます。
今回が1なので次に修正する際は2を入れます。
そしてoldSchemaVersionに以前のスキーマのバージョンが入っているので、0から2にマイグレーションしたい時等はこの値を見れば良さそうです。

新しいMigration

Migrationは下の書き方が推奨になりました。(2015/11/4)

let config = Realm.Configuration(
    schemaVersion: 1,
    migrationBlock: { migration, oldSchemaVersion in
        if (oldSchemaVersion < 1) {}
})
Realm.Configuration.defaultConfiguration = config

まとめ

Realmはマイグレーションも簡単に書けて良さそうでした。
新しいカラムのデフォルト値も柔軟に設定できそうで便利そうです。