プログラムを書こう!

実務や自作アプリ開発で習得した役に立つソフトウェア技術情報を発信するブログ

SwiftのデータベースRealmでテーブルを変更する。

この記事は2019年01月18日に投稿しました。

f:id:paveway:20190914064630j:plain

目次

  1. はじめに
  2. SwiftのデータベースRealmでテーブルを変更する
  3. おわりに

軽量・高速モバイルデータベースRealm入門

軽量・高速モバイルデータベースRealm入門

1. はじめに

こんにちは、iOSのエディタアプリPWEditorの開発者の二俣です。
PWEditorで使用しているSwiftのデータベースRealmでテーブルを変更する方法についてです。

目次へ

2. SwiftのデータベースRealmでテーブルを変更する

SwiftのデータベースRealmでテーブルを変更する方法ですが、

"テーブルを変更する" = "モデルクラスのプロパティを変更する"

事になります。

しかしこのままでは既存のデータとプロパティが異なるため、既存のデータにアクセスできなくなります。
そのためRealmでは、既存のデータを更新するためのマイグレーションという機能が用意されています。
マイグレーションは以下のように行います。

  1. Realm.Configuration.migrationBlockを利用して、マイグレーション処理を実行します。
  2. マイグレーション処理は、AppDelegate.application(application:didFinishLaunchingWithOptions)メソッド内で行なうようにします。
  3. スキーマのバージョンを Realm.Configuration.schemaVersionで設定します。
    初期値は0です。
    マイグレーションするたびに、1ずつカウントアップしていきます。
    マイグレーション処理はスキーマのバージョンを判断して、実行するようにします。

実装例

// モデルクラス(変更前)
import RealmSwift

class PersonalInfo: Object {

    // ID
    @objc dynamic var id = 0 // プライマリーキー項目(項目名は任意です)
    
    // 名
    @objc dynamic var firstName = ""
    
    // 姓
    @objc dynamic var lastName = ""

    /**
     プライマリキーのプロパティ名を返却します。
     
     - Returns: プライマリキーのプロパティ名
     */
    override static func primaryKey() -> String? {
        return "id"
    }
}
// モデルクラス(変更語)
import RealmSwift

class PersonalInfo: Object {

    // ID
    @objc dynamic var id = 0 // プライマリーキー項目(項目名は任意です)

    // フルネーム
    @objc dynamic var fullName = ""

    /**
     プライマリキーのプロパティ名を返却します。
     
     - Returns: プライマリキーのプロパティ名
     */
    override static func primaryKey() -> String? {
        return "id"
    }
}
// マイグレーション処理
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions: launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        // application(application:didFinishLaunchingWithOptions:)の中に書きます。
        let config = Realm.Configuration(
            // 新しいスキーマバージョンを設定します。
            // 以前のバージョンより大きくなければなりません。
            // (スキーマバージョンを設定したことがなければ、最初は0が設定されています)
            schemaVersion = 1,
            migrationBlock: { migraiton, oldSchemaVersion in
                // 最初のマイグレーションの場合、`oldSchemaVersion`は0です。
                if (oldSchemaVersion < 1) {
                    // enumerateObjects(ofType:_:)メソッドで保存されているすべての
                    // PersonalInfoオブジェクトを列挙します。
                    migration.enumerateObjects(ofType: PersonalInfo.className()) { oldObject, newObject in
                        // firstNameとlastNameをfullNameプロパティに結合します
                        let firstName = oldObject!["firstName"] as! String
                        let lastName = oldObject!["lastName"] as! String
                        newObject!["fullName"] = "\(firstName) \(lastName)"
                }
            )
        )

        // デフォルトRealmに新しい設定を適用します。
        Realm.Configuration.defaultConfiguration = config
    }
}

目次へ

3. おわりに

PWEditorでもアプリのバージョンを上げるにつれ、以前作成したデータベースのテーブル構成を変更する必要に迫られました。
その際このマイグレーション処理を利用してテーブル構成を変更しました。
マイグレーション処理のおかげで、案外簡単にテーブルを変更できました。
しかしテーブルを変更すると、既存の処理が動かなくなったり、クラッシュしたりするので、気をつかいいます。

プログラミング書籍なら翔泳社の通販『SEshop』

[改訂新版]Swift実践入門 ── 直感的な文法と安全性を兼ね備えた言語 (WEB+DB PRESS plus)

[改訂新版]Swift実践入門 ── 直感的な文法と安全性を兼ね備えた言語 (WEB+DB PRESS plus)

紹介している一部の記事のコードはGitlabで公開しています。
興味のある方は覗いてみてください。

目次へ


私が勤務しているニューラルでは、主に組み込み系ソフトの開発を行っております。
弊社製品のハイブリッドOS Bi-OSは高い技術力を評価されており、特に制御系や通信系を得意としています。
私自身はiOSモバイルアプリウィンドウズアプリを得意としております。
ソフトウェア開発に関して相談などございましたら、お気軽にご連絡ください。

また一緒に働きたい技術者の方も随時募集中です。
興味がありましたらご連絡ください。

EMAIL : info-nr@newral.co.jp / m-futamata@newral.co.jp
TEL : 042-523-3663
FAX : 042-540-1688

目次へ