如何执行 LinkingObject 的迁移?
How to perform migration of LinkingObject?
我需要执行迁移,不丢失 parent/owner。如何在迁移块中执行此操作?
迁移前
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{
}
这个问题的挑战是 LinkingObjects 不是持久化的——它们是计算出来的,所以不能直接迁移。
第二个挑战是原始卡片对象除了 'text' 变量之外没有任何持久属性。
这是完成这项工作的代码。我们正在获取新的 Decks cards 属性,迭代它们并更新 Card 对象中的每个所有者 属性 以指向新的 Deck。
一旦卡的所有者 属性 设置为该牌组,该牌组 linkingCards 属性 将 'pick that up' 因为它是计算出来的。
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
}
我需要执行迁移,不丢失 parent/owner。如何在迁移块中执行此操作?
迁移前
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{
}
这个问题的挑战是 LinkingObjects 不是持久化的——它们是计算出来的,所以不能直接迁移。
第二个挑战是原始卡片对象除了 'text' 变量之外没有任何持久属性。
这是完成这项工作的代码。我们正在获取新的 Decks cards 属性,迭代它们并更新 Card 对象中的每个所有者 属性 以指向新的 Deck。
一旦卡的所有者 属性 设置为该牌组,该牌组 linkingCards 属性 将 'pick that up' 因为它是计算出来的。
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
}