7

Swift アプリで realm.io を使用しています。アプリを運用しているので、移行を実行する必要があったのはこれが初めてです。モデルの 1 つを変更し、いくつかのフィールドを追加しました。

ドキュメントの例に従い、それが機能しない場合は github リポジトリの例を参照しました。おそらくドキュメントの例よりも複雑であると思いました。

appdelegate.swift ファイルにあるものは次のとおりです。

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

        print ("i'm in here")
        // Override point for customization after application launch.

        // Inside your application(application:didFinishLaunchingWithOptions:)

        window = UIWindow(frame: UIScreen.mainScreen().bounds)
        window?.rootViewController = UIViewController()
        window?.makeKeyAndVisible()

        // copy over old data files for migration
        let defaultPath = Realm.Configuration.defaultConfiguration.path!
        let defaultParentPath = (defaultPath as NSString).stringByDeletingLastPathComponent

        if let v0Path = bundlePath("default-v0.realm") {
            do {
                try NSFileManager.defaultManager().removeItemAtPath(defaultPath)
                try NSFileManager.defaultManager().copyItemAtPath(v0Path, toPath: defaultPath)
            } catch {}
        }

        let config = Realm.Configuration(
            // Set the new schema version. This must be greater than the previously used
            // version (if you've never set a schema version before, the version is 0).
            schemaVersion: 1,

            // Set the block which will be called automatically when opening a Realm with
            // a schema version lower than the one set above
            migrationBlock: { migration, oldSchemaVersion in
                // We haven’t migrated anything yet, so oldSchemaVersion == 0
                if (oldSchemaVersion < 1) {
                    // Nothing to do!
                    // Realm will automatically detect new properties and removed properties
                    // And will update the schema on disk automatically
                }
        })

        // define a migration block
        // you can define this inline, but we will reuse this to migrate realm files from multiple versions
        // to the most current version of our data model
        let migrationBlock: MigrationBlock = { migration, oldSchemaVersion in
            if oldSchemaVersion < 1 {

            }

            print("Migration complete.")
        }

        Realm.Configuration.defaultConfiguration = Realm.Configuration(schemaVersion: 1, migrationBlock: migrationBlock)

        // Tell Realm to use this new configuration object for the default Realm
        Realm.Configuration.defaultConfiguration = config

        // Now that we've told Realm how to handle the schema change, opening the file
        // will automatically perform the migration
        _ = try! Realm()


        return true
    }

print私が奇妙だと思うことはありません。私は何かを台無しにしていますか?私はそうでなければならないと仮定しています。

ドキュメンテーションには次のように書かれています。

// Inside your application(application:didFinishLaunchingWithOptions:)

let config = Realm.Configuration(
  // Set the new schema version. This must be greater than the previously used
  // version (if you've never set a schema version before, the version is 0).
  schemaVersion: 1,

  // Set the block which will be called automatically when opening a Realm with
  // a schema version lower than the one set above
  migrationBlock: { migration, oldSchemaVersion in
    // We haven’t migrated anything yet, so oldSchemaVersion == 0
    if (oldSchemaVersion < 1) {
      // Nothing to do!
      // Realm will automatically detect new properties and removed properties
      // And will update the schema on disk automatically
    }
  })

// Tell Realm to use this new configuration object for the default Realm
Realm.Configuration.defaultConfiguration = config

// Now that we've told Realm how to handle the schema change, opening the file
// will automatically perform the migration
let realm = try! Realm()

私が間違っていることはありますか?

4

4 に答える 4

2

これは意図したとおりに機能し、ダウングレード時に例外をスローします (バージョンが異なるブランチで作業している場合) などです。移行のサンプルもいくつか示されています。

    Realm.Configuration.defaultConfiguration = Realm.Configuration(
        // Update this number for each change to the schema.
        schemaVersion: 4,
        migrationBlock: { migration, oldSchemaVersion in
            if oldSchemaVersion < 2 {
                migration.enumerate(SomeObject.className()) { oldObject, newObject in
                    newObject!["newColumn"] = Enum.Unknown.rawValue
                }
            }
            if oldSchemaVersion < 3 {
                migration.enumerate(SomeOtherObject.className()) { oldObject, newObject in
                    newObject!["defaultCreationDate"] = NSDate(timeIntervalSince1970: 0)
                }
            }
            if oldSchemaVersion < 4 {
                migration.enumerate(SomeObject.className()) { oldObject, newObject in
                    // No-op.
                    // dynamic properties are defaulting the new column to true
                    // but the migration block is still needed
                }
            }
    })

明らかに、そのままではコンパイルされませSomeObjectんが、アイデアはわかります:)

于 2016-01-14T17:56:07.460 に答える
1

Realm Swift の「移行」の例からコードを完全にコピーし、そのまま貼り付けたようです。そのコードの多くは、サンプル アプリが実行されるたびに新しいデモ マイグレーションを実際に「セットアップ」するためのものであり、実際には通常の Realm マイグレーションには必要ありません。

レルムの移行には 2 つのコンポーネントがあります。

  1. オブジェクトのスキーマ バージョン番号をバンプしConfigurationます。レルム ファイルはバージョン 0 から始まり、新しい移行を行うたびにバージョンを 1 増やします。

  2. Realm スキーマ バージョンの増分ごとに複数回実行される移行ブロックを指定します。ブロック自体は必要ですが、その目的は、古い Realm ファイル内のデータをコピー/変換できるようにすることです。新しいフィールドを追加するだけの場合は、ブロックを空のままにしておくことができます。

UIViewController実装で Realm を使用している場合は、コードの前に移行コードを配置して、使用を開始するUIWindow前に移行が確実に行われるようにするUIViewControllerことをお勧めします (そうしないと、例外が発生します)。

いくつかのフィールドを追加するだけなので、必要なコードはこれだけです。

let migrationBlock: MigrationBlock = { migration, oldSchemaVersion in
    //Leave the block empty
}
Realm.Configuration.defaultConfiguration = Realm.Configuration(schemaVersion: 1, migrationBlock: migrationBlock)

window = UIWindow(frame: UIScreen.mainScreen().bounds)
window?.rootViewController = UIViewController()
window?.makeKeyAndVisible()
于 2016-01-14T05:22:18.177 に答える