環境

Xcode 9.2
Swift 4
RealmCocoa v3.0.2
iPhone SE Simulator 11.2

状況

Mastodonのクライアントを開発しています。
OAuth関連情報の永続化が必要なため、RealmSwiftを利用してデータを永続化しようとしています。

Realmで永続化しているモデルは次の2つです。

  • InstanceModel

    import Foundation
    import RealmSwift
    
    class InstanceModel: Object {
        @objc var id = UUID().uuidString
        @objc var instanceURL: String = ""
    }
    
  • ConsumerIdModel

    import Foundation
    import RealmSwift
    
    class ConsumerIdModel Object {
        @objc var id = ""
        @objc var clientId = ""
        @objc var client_secret = ""
        @objc var instanceModel : InstanceModel?
    }
    

永続化するモデルを生成保存している部分は次のコードです。

static func store(consumerIdStruct: ConsumerIdStruct, instanceUrl: String) {
    let instanceModel = InstanceModel()
    instanceModel.instanceURL = instanceUrl
    RealmHandler.writeInstanceModel(instanceModel: instanceModel)
    let consumerIdModel = ConsumerIdModel()
    consumerIdModel.id = consumerIdStruct.id
    consumerIdModel.clientId = consumerIdStruct.client_id
    consumerIdModel.client_secret = consumerIdStruct.client_secret
    consumerIdModel.instanceModel = instanceModel
    RealmHandler.writeConsumerIdModel(consumerIdModel: consumerIdModel)
}

永続化するモデルをRealmに書き込む処理は次のコードです。

extension RealmHandler {
    static func writeConsumerIdModel(consumerIdModel: ConsumerIdModel) { 
        let realm = try! Realm()
        try! realm.write {
            realm.add(consumerIdModel)
        }
    }

    static func writeInstanceModel(instanceModel: InstanceModel) {
        let realm = try! Realm()
        try! realm.write {
            realm.add(instanceModel)
        }
    }
}

ここまでで無事永続化ができていると思っています。

このあと次のようなコードで取り出そうとすると、保存されているInstanceModelの「数」は一致するのですが、「値」が一致しません。

extension RealmHandler {
    static func readInstanceModel(instanceUrl: String) -> InstanceModel? {
        let realm = try! Realm()
        let instances = Array(realm.objects(InstanceModel.self))
        for instance in instances {
            if instance.instanceUrl == instanceUrl {
                return instance
            }
        }
        return nil
    }

    static func readConsumerIdModel(instanceModel: InstanceModel) -> ConsumerIdModel? {
        let realm = try! Realm()
        let consumerIdModels = Array(realm.objects(ConsumerIdModel.self))
        for consumerIdModel in consumerIdModels {
            if consumerIdModel.instanceModel?.id == instanceModel.id {
                return consumerIdModel
            }
            return nil
        }
    }
}

一致しない時のデバッガログは次のようになります。
(instanceUrlは×で置き換えておりますが、表示上は期待したインスタンスのURLが格納されています)

(lldb) po instance
InstanceModel {
    id = D5837160-8E32-4E56-AC79-BF220AAD00AF;
    instanceURL = ××××;
}

(lldb) po instance.id
"FF65F00C-4F67-4E08-91CD-2607B031F945"

(lldb) po instance.instanceURL
""

(lldb)

挙動を確認すると、データを参照しようとしたときに新規データとして生成されている(UUID.uuidStringが別の値になっている)ようなので、Realmによる「取り出しデータの初期化」が完了していないように見えます。

試した解決策は次の2つです。

  • RealmSwift.Results<>を通常のArrayに変換する → 失敗
  • NSThread.sleepforTimeintervalを利用し処理を一時停止する → 失敗

おそらく初歩的なことを見落としていると思いますが、完全に頭が止まってしまいました。
解決策をご存じの方がいらっしゃいましたらご教授いただけると幸いです。