Realm (Swift):如何在迁移过程中获取 MutableSet 数据?
Realm (Swift): How to get at MutableSet data during migration?
我有一个本地 Realm(使用 RealmSwift API 版本 10.15.1),它有一个 Player
我正在尝试迁移的对象。 Player
当前包含名为 preferredPositions
的字段,它是一个 MutableSet<PositionClass>
。 Player
的定义如下所示:
@objc final class Player: Object {
@Persisted(primaryKey: true) var playerId: ObjectId
@Persisted var name: String = ""
@Persisted var preferredPositions: MutableSet<PositionClass> = MutableSet<PositionClass>()
...
}
和 PositionClass
看起来像这样:
class PositionClass: Object {
@Persisted(primaryKey: true) var positionClassId: String = ""
@Persisted var name: String = ""
@Persisted var order: Int = 0
@Persisted var abbreviation: String = ""
...
}
我想进行迁移,将 preferredPositions
从 MutableSet<PositionClass>
更改为 List<PositionClass>
,因为现在我想订购 preferredPositions
。
所以新的 Player
看起来像:
@objc final class Player: Object {
@Persisted(primaryKey: true) var playerId: ObjectId
@Persisted var name: String = ""
@Persisted var preferredPositions: List<PositionClass> = List<PositionClass>()
...
}
但是,我无法弄清楚迁移配置中访问 preferredPositions
数据的魔法咒语。
在我的迁移中我有:
let schemaVersion: UInt64 = 22
let config = Realm.Configuration(schemaVersion: schemaVersion,
migrationBlock: { migration, oldSchemaVersion in
...
if (oldSchemaVersion < 22) {
migration.enumerateObjects(ofType: Player.className()) { oldObject, newObject in
if let preferredPositionsSet: MutableSet<PositionClass> = oldObject!["preferredPositions"] as? MutableSet<PositionClass> {
let preferredPositionsList: List<PositionClass> = List()
preferredPositionsSet.forEach { (positionClass: PositionClass) in
preferredPositionsList.append(positionClass)
}
newObject!["preferredPositions"] = preferredPositionsList
} else {
NSLog("preferredPositionsSet is nil.")
}
}
}
})
Realm.Configuration.defaultConfiguration = config
但是线
let preferredPositionsSet: MutableSet<PositionClass> = oldObject!["preferredPositions"] as? MutableSet<PositionClass>
总是returns 零。我查看了调试器,似乎 oldObject!["preferredPositions"]
是 MutableSet<PositionClass>
。例如,如果我添加代码:
let preferredPositionsAny = oldObject!["preferredPositions"]
然后在它显示的调试器中查看 preferredPositionsAny
:
所以,基础类型是正确的,但我不知道如何正确地理解它。
或者我应该以不同的方式进行迁移吗?
代码 TL;DR:
let schemaVersion: UInt64 = 22
let config = Realm.Configuration(schemaVersion: schemaVersion,
migrationBlock: { migration, oldSchemaVersion in
...
if (oldSchemaVersion < 22) {
migration.enumerateObjects(ofType: Player.className()) { oldObject, newObject in
let newRealm = newObject!.realm
let preferredPositionsList: List<PositionClass> = List()
let preferredPositionsSet = oldObject!.dynamicMutableSet("preferredPositions")
preferredPositionsSet.forEach { positionClass in
if let newPositionClass = newRealm?.object(ofType: PositionClass.self, forPrimaryKey: positionClass["positionClassId"]) {
preferredPositionsList.append(newPositionClass)
}
}
newObject!["preferredPositions"] = preferredPositionsList
}
}
更完整的答案:
有几件事我弄错了:
- “旧”对象的数据类型不是
MutableSet<PositionClass>
,而是 MutableSet<DynamicObject>
。这就是为什么转换为 MutableSet<PositionClass>
总是 returning nil
.
- 还有一种更清晰的方法来获取旧的
MutableSet
,所以不用调用
let preferredPositionsSet = oldObject!["preferredPositions"] as! MutableSet<DynamicObject>
从我发现
let preferredPositionsSet = oldObject!.dynamicMutableSet("preferredPositions")
其中似乎有 return 相同的对象,但同样更清楚一点
- 从这个答案:,要用现有的
PositionClass
实例重新填充新的 List
(而不是创建新实例),您需要从中获取数据境界。但是为了得到一个参数来获取数据。由于“旧”MutableSet
包含 DynamicObject
,您需要使用命名字段的 DynamicObject 方法访问它,例如positionClass["positionClassId"]
而不是访问实际基础对象类型上的 属性,例如positionClass.positionClassId
。这就是
let newRealm = newObject!.realm
if let newPositionClass = newRealm?.object(ofType: PositionClass.self, forPrimaryKey: positionClass["positionClassId"]) {
...
来自.
我有一个本地 Realm(使用 RealmSwift API 版本 10.15.1),它有一个 Player
我正在尝试迁移的对象。 Player
当前包含名为 preferredPositions
的字段,它是一个 MutableSet<PositionClass>
。 Player
的定义如下所示:
@objc final class Player: Object {
@Persisted(primaryKey: true) var playerId: ObjectId
@Persisted var name: String = ""
@Persisted var preferredPositions: MutableSet<PositionClass> = MutableSet<PositionClass>()
...
}
和 PositionClass
看起来像这样:
class PositionClass: Object {
@Persisted(primaryKey: true) var positionClassId: String = ""
@Persisted var name: String = ""
@Persisted var order: Int = 0
@Persisted var abbreviation: String = ""
...
}
我想进行迁移,将 preferredPositions
从 MutableSet<PositionClass>
更改为 List<PositionClass>
,因为现在我想订购 preferredPositions
。
所以新的 Player
看起来像:
@objc final class Player: Object {
@Persisted(primaryKey: true) var playerId: ObjectId
@Persisted var name: String = ""
@Persisted var preferredPositions: List<PositionClass> = List<PositionClass>()
...
}
但是,我无法弄清楚迁移配置中访问 preferredPositions
数据的魔法咒语。
在我的迁移中我有:
let schemaVersion: UInt64 = 22
let config = Realm.Configuration(schemaVersion: schemaVersion,
migrationBlock: { migration, oldSchemaVersion in
...
if (oldSchemaVersion < 22) {
migration.enumerateObjects(ofType: Player.className()) { oldObject, newObject in
if let preferredPositionsSet: MutableSet<PositionClass> = oldObject!["preferredPositions"] as? MutableSet<PositionClass> {
let preferredPositionsList: List<PositionClass> = List()
preferredPositionsSet.forEach { (positionClass: PositionClass) in
preferredPositionsList.append(positionClass)
}
newObject!["preferredPositions"] = preferredPositionsList
} else {
NSLog("preferredPositionsSet is nil.")
}
}
}
})
Realm.Configuration.defaultConfiguration = config
但是线
let preferredPositionsSet: MutableSet<PositionClass> = oldObject!["preferredPositions"] as? MutableSet<PositionClass>
总是returns 零。我查看了调试器,似乎 oldObject!["preferredPositions"]
是 MutableSet<PositionClass>
。例如,如果我添加代码:
let preferredPositionsAny = oldObject!["preferredPositions"]
然后在它显示的调试器中查看 preferredPositionsAny
:
所以,基础类型是正确的,但我不知道如何正确地理解它。
或者我应该以不同的方式进行迁移吗?
代码 TL;DR:
let schemaVersion: UInt64 = 22
let config = Realm.Configuration(schemaVersion: schemaVersion,
migrationBlock: { migration, oldSchemaVersion in
...
if (oldSchemaVersion < 22) {
migration.enumerateObjects(ofType: Player.className()) { oldObject, newObject in
let newRealm = newObject!.realm
let preferredPositionsList: List<PositionClass> = List()
let preferredPositionsSet = oldObject!.dynamicMutableSet("preferredPositions")
preferredPositionsSet.forEach { positionClass in
if let newPositionClass = newRealm?.object(ofType: PositionClass.self, forPrimaryKey: positionClass["positionClassId"]) {
preferredPositionsList.append(newPositionClass)
}
}
newObject!["preferredPositions"] = preferredPositionsList
}
}
更完整的答案:
有几件事我弄错了:
- “旧”对象的数据类型不是
MutableSet<PositionClass>
,而是MutableSet<DynamicObject>
。这就是为什么转换为MutableSet<PositionClass>
总是 returningnil
. - 还有一种更清晰的方法来获取旧的
MutableSet
,所以不用调用
let preferredPositionsSet = oldObject!["preferredPositions"] as! MutableSet<DynamicObject>
从我发现
let preferredPositionsSet = oldObject!.dynamicMutableSet("preferredPositions")
其中似乎有 return 相同的对象,但同样更清楚一点
- 从这个答案:,要用现有的
PositionClass
实例重新填充新的List
(而不是创建新实例),您需要从中获取数据境界。但是为了得到一个参数来获取数据。由于“旧”MutableSet
包含DynamicObject
,您需要使用命名字段的 DynamicObject 方法访问它,例如positionClass["positionClassId"]
而不是访问实际基础对象类型上的 属性,例如positionClass.positionClassId
。这就是
let newRealm = newObject!.realm
if let newPositionClass = newRealm?.object(ofType: PositionClass.self, forPrimaryKey: positionClass["positionClassId"]) {
...
来自.