27449


今あるrealmデータを保持したまま、マイグレーションでモデルの構造を変更したいのですが、方法がわかりません。

具体的には、Realmデータクラスの`ThreadData`内にある `dynamic var aaaaa =
""`を構造から削除し、新たに`dynamic var bbbbb = ""`を追加したいです。  
そこで、下記の通り記述しましたが、エラー内容にあるように、`aaaaa`は削除できておらず、`bbbbb`は追加できていないようです。  
さらに、別のrealmを利用している他のクラスの`let realm = try!
Realm()`でEXC_BAD_INSTRUCTIONエラーとなります。

なお、今あるdefalut.realmを削除して再度生成した場合は、これらの構造変更は反映されています。

[code]

    fatal error: 'try!' expression unexpectedly raised an error: Error Domain=io.realm Code=10 "Migration is required due to the following errors:
    - Property 'aaaaa' is missing from latest object model.
    - Property 'bbbbb' has been added to latest object model." UserInfo={NSLocalizedDescription=Migration is required due to the following errors:
    - Property 'aaaaa' is missing from latest object model.
    - Property 'bbbbb' has been added to latest object model., Error Code=10}: file /Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-703.0.18.8/src/swift/stdlib/public/core/ErrorType.swift, line 54
    
[/code]

`ThreadData`

[code]

    import Foundation
    import RealmSwift
    class ThreadData: Object {
        //dynamic var aaaaa = ""
        dynamic var bbbbb = ""
    }
    
[/code]

`AppDelegate`

[code]

    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        // Override point for customization after application launch.
        //        UIApplication.sharedApplication().setStatusBarStyle(UIStatusBarStyle.LightContent, animated: true)
    
    
        let migrationBlock: MigrationBlock = { migration, oldSchemaVersion in
            if oldSchemaVersion < 1 {
                migration.enumerate(TeamData.className()) { oldObject, newObject in
                    if oldSchemaVersion < 1 {
                    }
                }
            }
            if oldSchemaVersion < 3 {
                migration.enumerate(ThreadData.className()) { oldObject, newObject in
                    newObject!["bbbbb"] as! String
                    let weaponID = oldObject!["aaaaa"] as! String
    
    
                }
            }
            print("Migration complete.")
        }
    
        Realm.Configuration.defaultConfiguration = Realm.Configuration(schemaVersion: 4, migrationBlock: migrationBlock)
        return true
    }
    
[/code]

`NoUserView`

[code]

    import UIKit
    import RealmSwift
    
    class NoUserView: UIView, UITextViewDelegate, PlacePickerViewDelegate {
    
        var finishUserRegisterButton : UIButton = UIButton()
    
    //中略
    
        let realm = try! Realm()//こちらでエラーが発生します。
        let user = PersonalData()
    
    
    
        override init(frame:CGRect) {
            super.init(frame:frame)
            //setupCustomView()
        }
    
        required init?(coder aDecoder: NSCoder) {
            fatalError("init(coder:) has not been implemented")
            //setupCustomView()
        }
    
[/code]


CC BY-SA 3.0
2016-07-07T15:51:54.167
27442
2016-07-08T11:24:57.590
2016-07-08T11:17:48.760
15277
15277
question
swift realm
Migrationによる、Realmモデル構造の追加と削除


エラーの内容はプロパティが追加・削除できていないのではありません。モデルの定義が変更されていて既存のデータファイルと合っていないので、マイグレーションが必要、というエラーです。つまり、モデルは変更されていますが、マイグレーションが正しく行われていません。

Realmのマイグレーションは

  1. スキーマバージョンを上げることでデータ構造が変わったことをRealmに通知し、
  2. 必要に応じて過去のデータ構造から新しいデータ構造にデータを移行

という２つの処理があります。データを移行が必要ない（新しく増えたプロパティは空でいい）場合は「2」は必要ありません。（スキーマバージョンを上げるだけでマイグレーションブロックは書かなくて良い）

さて、書かれているエラーが出ているということは、「１」の手順で、より大きいスキーマバージョンが正しく設定されてないということになります。

おそらく原因は、`schemaVersion`を`4`にしていますが、数え間違えていてすでにファイルのスキーマバージョンは`4`なのだと思います。`schemaVersion`を`5`以上にしてみてください。

または、`NoUserView`がStoryboardで使われている場合、`application(application:,didFinishL‌​aunchingWithOptions:)`が呼ばれるより前にStoryboardによってメンバ変数の`let
realm = try! Realm()`が呼ばれてしまうので、マイグレーションの設定がされる前にRealmが作られてしまいます。

このように、Storyboardで使われるビューのメンバ‌​変数でRealmを初期化している場合、その部分を`lazy var realm = try!
Realm()`にしてください。そうすることで、`realm`変数が最初に使われるときまで初期化を遅らせることができます。


CC BY-SA 3.0
2016-07-08T03:37:20.743
27449
2016-07-08T11:24:57.590
2016-07-08T11:24:57.590
5519
5519
27442
answer