在领域快速中重命名类的最佳方式 [英] best way to rename a class in Realm swift

查看:30
本文介绍了在领域快速中重命名类的最佳方式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在iOS项目中使用"公共"库。此库创建领域数据库。到目前为止,我只在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中,我不需要更改任何内容。

除了我的本地领域数据库之外,这一切都很好。我有很多Collection对象应该重命名为SpecialCollection(因为领域在SWIFT下使用objc)。我想执行迁移来做到这一点,但是显然还没有一种受支持的方式来做到这一点?我注意到GitHub上关于这个问题的罚单正在"关注",但不幸的是,仍然没有公布的解决方案来解决这个问题。

我的所有Collection对象都包含List对象(由此得名)。因此,我尝试在迁移中对所有Collection对象运行枚举.我只需要使用较旧的对象,并使用新名称创建一个新对象,如下所示:

 migration.enumerateObjects(ofType: "Collection", { (oldObject, _) in
    migration.create("SpecialCollection", value: oldObject)
 }
但由于oldObject具有其他对象的列表,领域的迁移将尝试创建任何List对象中的所有项目.无法执行此操作,因为它会创建具有相同primaryKey值的对象(导致崩溃)。

因此,我不能保留旧名称(集合),也不能转换为新名称,我不能只是丢弃用户的数据。所以,我真的陷入僵局了。

区块引用

在创建新对象之前,我尝试修改oldObject,但您无法在迁移中更改oldObject

唯一的规则是必须保留旧数据,我不能在这里只破坏用户的领域。

谢谢您在这方面的帮助。非常感谢。

推荐答案

我昨晚遇到了非常类似的问题。我有几个领域类要重命名,其中一个类有一个引用第二个类的List属性。因此,与您的问题相比,唯一的区别是我也重命名了ItemObject类。

我是这样做的:

  1. 首先迁移集合类,创建SpecialCollection。
  2. 迁移时,遍历集合列表并创建新的 为每个ItemObject指定SpecialItemObject,并将其追加到新列表。
  3. 删除每个ItemObject。
  4. 现在枚举所有剩余的ItemObject 在领域中创建一个新的SpecialItemObject并映射其值 完毕。原因是可能有其他ItemObject漂浮在周围 在您的领域中,不绑定到列表。
  5. 删除所有剩余的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或其他地方的可可领域几乎找不到任何关于这个问题的答案。上面的示例与您要求的唯一不同之处在于,您没有要求重命名ItemObject类。您可以尝试只创建新的ItemObject对象,并以与我在示例中相同的方式映射属性。我不明白为什么它不管用。自从我昨晚测试了一些迁移以证明它是可靠的以来,我已经提供了我是如何解决我自己的问题的确切示例。

因为你的问题已经提了将近5个月了,我真的只是把这个答案贴给后人。希望这对某人有帮助!

在iOS 11.3 SIM/Xcode 9.3/SWIFT 4.1上使用领域3.3.2测试

这篇关于在领域快速中重命名类的最佳方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆