質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.04%

Realm Swiftのマイグレーションができない

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,276

score 35

前提・実現したいこと

Xcode にて Realm Swift を利用しアプリを App Store に公開しています。

この度、データモデルのプロパティを1つ増やすために、マイグレーションが必要になると思い
AppDelegate内に実装しましたが、エラーが発生してしまいます。
おそらく、マイグレーションの方法が間違っていて失敗しているとは思うのですが、
か行ける方法が解りませんでした。

発生している問題・エラーメッセージ

objc[29350]: Class PLBuildVersion is implemented in both /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/PrivateFrameworks/AssetsLibraryServices.framework/AssetsLibraryServices (0x11f1e0cc0) and /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk/System/Library/PrivateFrameworks/PhotoLibraryServices.framework/PhotoLibraryServices (0x11eff76f0). One of the two will be used. Which one is undefined.
fatal error: 'try!' expression unexpectedly raised an error: Error Domain=io.realm Code=10 "Migration is required due to the following errors:
- Property 'RegisteredUQ.isCalculationTarget' has been added." UserInfo={NSLocalizedDescription=Migration is required due to the following errors:
- Property 'RegisteredUQ.isCalculationTarget' has been added., Error Code=10}: file /Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-802.0.53/src/swift/stdlib/public/core/ErrorType.swift, line 182
(lldb) 

該当のソースコード

データモデル

import RealmSwift

class RegisteredUQ: Object {

    // Bool, Int, Float, Double, String, NSData(), NSDate(), List<Class>()

    // SchemaVersion 0
    dynamic var id = 0
    dynamic var useDate = NSDate()
    dynamic var usedFor = ""
    dynamic var usePeriod = 0.0

    // SchemaVersion 1
    dynamic var isCalculationTarget = true

    override static func primaryKey() -> String? {
        return "id"
    }
}

AppDelegate

import UIKit
import UserNotifications
import RealmSwift

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

    var window: UIWindow?

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

        realmMigration()

    中略        

        return true
    }

    中略

    // Realmのマイグレーション
    func realmMigration() {
        let config = Realm.Configuration(
            // 新しいスキーマバージョンを設定します。以前のバージョンより大きくなければなりません。
            // (スキーマバージョンを設定したことがなければ、最初は0が設定されています)
            schemaVersion: 1,

            // マイグレーション処理を記述します。古いスキーマバージョンのRealmを開こうとすると
            // 自動的にマイグレーションが実行されます。
            migrationBlock: { migration, oldSchemaVersion in
                // 最初のマイグレーションの場合、`oldSchemaVersion`は0です
                if (oldSchemaVersion < 1) {
                      // 何もする必要はありません!
                      // Realmは自動的に新しく追加されたプロパティと、削除されたプロパティを認識します。
                      // そしてディスク上のスキーマを自動的にアップデートします。
                }
        })

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

        // Realmファイルを開こうとしたときスキーマバージョンが異なれば、
        // 自動的にマイグレーションが実行されます
        let realm = try! Realm()

        print(realm, "Realm")
        print(config,"Realm Version")
    }
}

エラー発生箇所

エラー発生箇所

試したこと

試しにスキーマバージョンを10にして見ても同じくエラーでした。

補足情報(言語/FW/ツール等のバージョンなど)

Xcode 8.3.3 Swift 3.1

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

HistoryViewControllerが、アプリ起動時に最初に表示される初期ViewControllerになっているのであれば、AppDelegateのdidFinishLaunchingWithOptionsが呼ばれる前にHistoryViewControllerのインスタンスが生成され、プロパティの初期化が行われます。

HistoryViewControllerのプロパティの定義を

var registeredUQs: Results<RegisteredUQ>!


として、viewDidLoadで  

registeredUQs = try! Realm().objects(RegisteredUQ.self).sorted(byKeyPath: "useDate", ascending: false)


を実行するよう変更すれば、HistoryViewControllerがRealmを使用する前にdidFinishLaunchingWithOptionsが呼ばれて、マイグレーション処理が動作するはずです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/07/29 08:40

    ご回答ありがとうございます。
    HistoryViewControllerはTabBarControllerのタブの一つとなっており、最初に表示されるのは同じくTabBarController下のHomeViewControllerとなっております。

    早速試してみたところ、
    ① var registetedUQs: Results<RegistetedUQ>! に対して
    エラー:Use of undeclared type 'RegistetedUQ'

    ② override func viewDidLoad() {
    super.viewDidLoad()

    registetedUQs = try! Realm().objects(RegistetedUQ.self).sorted(byKeyPath: "useDate", ascending: false)
    } に対して、
    エラー:Use of unresolved identifier 'RegistetedUQ'
    が発生しました。

    ② については registetedUQs = try! Realm().objects(registetedUQ.self).sorted(byKeyPath: "useDate", ascending: false) に直せとの提案があり、従ったらエラーは消えました。

    何か僕の単純な思い違いがありそうです。
    ご教示いただけないでしょうか?

    キャンセル

  • 2017/07/29 09:45

    すみません。回答にタイプミスがありますね。
    RegistetedUQじゃなくてRegisteredUQですね。
    回答を修正しておきました。

    キャンセル

  • 2017/07/29 10:36

    TakeOne様、ありがとうございます。
    無事にマイグレーションを行うことができました!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.04%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る