swift - Realm Swift 错误:无法直接创建嵌入式对象
问题描述
我正在尝试将具有 type 属性的对象迁移List<String>
到 type List<ChildObject>
where ChildObject
is a custom EmbeddedObject
。
例子
这就是我的意思:
import RealmSwift
final class ParentObject: Object {
// Previously, this property was of type `List<String>`.
@Persisted public var children: List<ChildObject>
}
final class ChildObject: EmbeddedObject {
@Persisted var name = ""
}
我正在使用此代码执行迁移,这会产生错误:
不能直接创建嵌入对象
let configuration = Realm.Configuration(schemaVersion: 1) { migration, oldSchemaVersion in
if oldSchemaVersion < 1 {
migration.enumerateObjects(ofType: ParentObject.className()) { oldObject, newObject in
let childrenStrings = oldObject!["children"] as! List<DynamicObject>
let childrenObjects = newObject!["children"] as! List<MigrationObject>
// I'm trying to retain the previous values for `children` (of type `String`)
// where each value is used as the `name` property of a new `ChildObject`.
for string in childrenStrings {
childrenObjects.append(
// This line produces the error :(
migration.create(ChildObject.className(), value: [string])
)
}
}
}
}
let realm = try! Realm(configuration: configuration)
问题
如何在保留先前值的同时执行迁移?
解决方案
最简单的做法是Dictionary
使用每个子对象的所有属性名称/值对创建一个,并List
使用这些对的数组创建一个完整的新对象。
但首先您需要String
从旧List
的children
. 这是必要的原因是因为 Realm 并不将元素表示List<String>
为实际的String
(它是一个结构)。description
我们可以从字段中提取实际值:
childrenStrings
.map { String(describing: $0) }
一旦你有了名字,你就可以ChildObject
用Dictionary
. 请注意,您必须在Dictionary
. 由于我们只有一个,称为“名称”,因此我们包括:
childrenStrings
.map { String(describing: $0) }
.map { ["name": $0] }
你的错误信息说:
不能直接创建嵌入对象
但是,您可以使用对应的Array
和每个对应的对象来创建新对象。综上所述,我们有:Dictionary
Array
List
Dictionary
ChildObject
migration.enumerateObjects(ofType: ParentObject.className()) { oldObject, newObject in
let childrenStrings = oldObject!["children"] as! List<DynamicObject>
newObject?.setValue(
Array(
childrenStrings
.map { String(describing: $0) }
.map { ["name": $0] }
),
forKey: "children"
)
}