如何执行LinkingObject的迁移?

时间:2019-12-10 17:00:29

标签: ios swift migration realm realm-migration

我需要执行迁移,而又不丢失父母/所有者。如何在迁移块中做到这一点?

迁移之前

class Deck : Object {

    @objc dynamic var name : String = ""

    var cards = List<Card>()

}
class Card : Object {

    @objc dynamic var text = ""

    var parentCategory = LinkingObjects(fromType: Deck.self, property: "cards")

}

迁移后

class Deck : Object {

    @objc dynamic var name : String = ""

    let cards = LinkingObjects(fromType: Card.self, property: "owner")

}
class Card : Object {


    @objc dynamic var text = ""

    @objc dynamic var owner : Deck?


}



在新版本的应用中,当我制作新卡时,我会像这样设置父级:

let decks = realm.objects(Deck.self)
owner = decks[index]

我只需要这样做,但是在迁移的情况下:

 let realm = try! Realm()
        let decks : Results<Deck>? = realm.objects(Deck.self)
        do {
            try realm.write {
                if decks!.count > 0 {
                    for indexOfDeck in 0...decks!.count - 1 {
                        if decks![indexOfDeck].cards.count > 0 {
                            for indexOfCard in 0...decks![indexOfDeck].cards.count - 1 {
                                                       decks![indexOfDeck].cards[indexOfCard].owner = decks![indexOfDeck]

                                                   }
                        }

                    }
                }

            }

        }catch{

    } 

1 个答案:

答案 0 :(得分:0)

这个问题的挑战在于LinkingObjects不持久-它们是经过计算的,因此不能直接迁移。

第二个挑战是原始卡片对象除了'text'变量外没有其他任何持久属性。

这是完成任务的代码。我们将获得新的Decks cards 属性,对其进行迭代,并更新Card对象中的每个owner属性,使其指向新的Deck。

将卡的所有者属性设置为该卡片组后,Deck的linkingCards属性将“收集”,因为它是经过计算的。

let vers = UInt64(1)
let config = Realm.Configuration( schemaVersion: vers, migrationBlock: { migration, oldSchemaVersion in
     print(oldSchemaVersion)
     if (oldSchemaVersion < vers) {
        print("  performing migration")

         migration.enumerateObjects(ofType: Deck.className()) { oldDeck, newDeck in
            let cards = newDeck!["cards"] as! List<MigrationObject>
            for card in cards {
                card["owner"] = newDeck
            }
         }
     } else {
        print("no migration needed")
    }
 })

我的原始对象看起来像这样,应该与问题中的对象匹配

class Deck : Object {
    @objc dynamic var name : String = ""
    var cards = List<Card>() //current
}

class Card : Object {
    @objc dynamic var text = ""
    var parentCategory = LinkingObjects(fromType: Deck.self, property: "cards") //current
}

然后更新的对象看起来像这样

class Deck : Object {
    @objc dynamic var name : String = ""
    var cards = List<Card>() //current
    let linkingCards = LinkingObjects(fromType: Card.self, property: "owner") //new
}

class Card : Object {
    @objc dynamic var text = ""
    var parentCategory = LinkingObjects(fromType: Deck.self, property: "cards") //current
    @objc dynamic var owner : Deck? //new
}