gpt4 book ai didi

ios - 在 Realm swift 中重命名类的最佳方法

转载 作者:搜寻专家 更新时间:2023-10-31 21:46:29 26 4
gpt4 key购买 nike

我在我的 iOS 项目中使用了一个“通用”库。这个库创建了一个 Realm 数据库。到目前为止,我一直只在 iOS 项目上使用这个库。我现在想在 macOS 项目中使用同一个库。它基于 Foundation,不使用 UIKit,为什么不呢?

问题是:我有一个名为 Collection

的 Realm 类

Collection 也是标准 Swift 协议(protocol)的名称。

虽然我已经能够在我的 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),也不能转换为新名称,并且我不能只是丢弃用户的数据。所以,我真的陷入了僵局。

block 引用

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

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

在此感谢您的帮助。非常感谢。

最佳答案

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

我是这样做的:

  1. 首先迁移您的 Collection 类,创建 SpecialCollection。
  2. 在迁移时,遍历集合的列表并创建新的每个 ItemObject 的 SpecialItemObject 并将其附加到新列表。
  3. 删除每个 ItemObject。
  4. 现在枚举所有剩余的 ItemObject在 Realm 中并创建一个新的 SpecialItemObject 并映射其值超过。原因是可能有其他 ItemObject 漂浮在周围在您的 Realm 内,不受列表限制。
  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 或 SO 或其他地方的 cocoa-realm 中几乎没有发现其中的大部分内容。上面的示例与您所要求的唯一不同之处在于您没有要求重命名您的 ItemObject 类。您可以尝试创建新的 ItemObject 对象并按照我在示例中显示的相同方式映射属性。我不明白为什么它不起作用。我已经准确地提供了我如何解决我自己的问题的示例,因为我昨晚测试了一些迁移以证明它是可靠的。

由于您的问题已经提出将近 5 个月了,我真的只是为了后代而发布这个答案。希望这对某人有帮助!

在 iOS 11.3 sim/Xcode 9.3/Swift 4.1 上使用 Realm 3.3.2 测试

关于ios - 在 Realm swift 中重命名类的最佳方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47914361/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com