我在iOS项目中使用“常用”库。该库创建一个Realm数据库。到目前为止,我一直在iOS项目中使用这个库。我想现在使用与macOS项目相同的库。这是基于Foundation
,并且不使用UIKit
,为什么不呢?
问题在于:我有一个名为 Collection
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
。
唯一的规则是必须保留旧数据,我不能在这里破坏用户的领域。
感谢您的帮助。非常感谢。
答案 0 :(得分:0)
昨晚我遇到了一个非常类似的问题。我有一些我想要重命名的Realm类,其中一个有一个List属性引用第二个类。因此,与您的问题相比,唯一的区别是我也重命名了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进行测试