在Realm swift中重命名类的最佳方法
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Realm swift中重命名类的最佳方法相关的知识,希望对你有一定的参考价值。
我在ios项目中使用了“通用”库。该库创建一个Realm数据库。到目前为止,我一直在iOS项目中使用这个库。我想现在使用与macOS项目相同的库。这是基于Foundation
,并没有使用UIKit
,为什么不呢?
这是问题:我有一个名为Collection
的Realm类
Collection
也是标准Swift协议的名称。
虽然我已经能够在我的iOS项目中逃脱这个名称冲突,但出于某种原因,我不能在我的MacOS项目上做同样的事情 - 它创建了一个名称集合。
我读到了可以这样使用的符号:
@objc(SpecialCollection)
class Collection: Realm.Object {
let items: List<ItemObject>
let name: String
let url: String
....
}
因此,这解决了名称冲突问题。在ObjC中,名称会有所不同,但在Swift中,我不需要改变任何东西。
除了我的本地Realm数据库之外,这一切都很好。我有很多Collection
对象应该重命名为SpecialCollection
(因为Realm在Swift下使用ObjC)。我想执行迁移来执行此操作,但显然没有支持的方法来执行此操作吗?我注意到github上关于这个问题被“观看”的门票,但不幸的是,仍然没有已发布的解决方案来解决这个问题。
我所有的Collection
对象都包含List
对象(因此得名)。所以,我尝试在迁移中对所有Collection
对象运行枚举...我只需要使用旧对象,并使用新名称创建一个新对象,如下所示:
migration.enumerateObjects(ofType: "Collection", { (oldObject, _) in
migration.create("SpecialCollection", value: oldObject)
}
但由于oldObject
有一个其他对象的列表,Realm的迁移将尝试创建任何List
对象中的所有项目......这是无法完成的,因为它创建具有相同primaryKey
值的对象(导致崩溃)。
所以,我不能保留旧名称(Collection),我无法转换为新名称,我不能只是删除用户的数据。所以,我真的陷入了僵局。
大段引用
我尝试在创建新对象之前修改oldObject
,但是您无法在迁移中更改oldObject
。
唯一的规则是必须保留旧数据,我不能在这里破坏用户的领域。
感谢您的帮助。非常感谢。
我昨晚遇到了一个非常类似的问题。我有一些我想要重命名的Realm类,其中一个有一个List属性引用第二个类。因此,与您的问题相比,唯一的区别是我也重命名了ItemObject类。
所以这就是我做的方式:
- 首先迁移Collection类,创建SpecialCollection。
- 迁移时,遍历Collection的列表并为每个ItemObject创建新的SpecialItemObject并将其附加到新列表。
- 删除每个ItemObject。
- 现在枚举域中剩余的所有ItemObject并创建一个新的SpecialItemObject并将其值映射到。原因是您的领域中可能有其他ItemObject浮动,而不是绑定到列表。
- 删除所有剩余的ItemObject。
migration.enumerateObjects(ofType: "Collection")
{ (oldObject, newObject) in
let specialCollection = migration.create(SpecialCollection.className())
specialCollection["name"] = oldObject!["name"]
specialCollection["url"] = oldObject!["url"]
if let oldItems = oldObject!["items"] as? List<MigrationObject>,
let newItems = specialCollection["items"] as? List<MigrationObject>
{
for oldItem in oldItems
{
let newItem = migration.create(SpecialItemObject.className())
newItem["name"] = oldItem["name"] // You didn't specify what was in your ItemObject so this example just assumes a name property.
newItems.append(newItem)
migration.delete(oldItem)
}
}
}
migration.deleteData(forType: "Collection")
// Now migrate any remaining ItemObject objects that were not part of a Collection.
migration.enumerateObjects(ofType: "ItemObject")
{ (oldObject, newObject) in
let newItem = migration.create(SpecialItemObject.className())
newItem["name"] = oldItem["name"]
}
// Now let's be sure we'll have no further ItemObject in our entire Realm.
migration.deleteData(forType: "ItemObject")
所以这就是我昨晚在GitHub或SO或其他地方的可可领域中发现大部分内容之后我自己解决的问题。上面的示例仅与您提出的要求重命名ItemObject类的内容不同。您可以尝试创建新的ItemObject对象并以我在示例中显示的相同方式映射属性。我不明白为什么它不起作用。我已经提供了我的例子,我是如何解决自己的问题,因为我昨晚测试了一些迁移以证明它是可靠的。
由于你的问题差不多5个月了,我真的只是为后人发布这个答案。希望这有助于某人!
在iOS 11.3 sim / Xcode 9.3 / Swift 4.1上使用Realm 3.3.2进行测试
以上是关于在Realm swift中重命名类的最佳方法的主要内容,如果未能解决你的问题,请参考以下文章
在 Swift 基于文档的应用程序中重命名 Document 类