Dan*_*row 5 macos realm ios swift realm-migration
我在我的 iOS 项目中使用了一个“通用”库。这个库创建了一个 Realm 数据库。到目前为止,我只在 iOS 项目中使用过这个库。我现在想在 macOS 项目中使用相同的库。它是Foundation基于的,不使用UIKit,为什么不呢?
问题是:我有一个名为的 Realm 类 Collection
Collection 也是标准 Swift 协议的名称。
虽然我已经能够在我的 iOS 项目上摆脱这个名称冲突,但出于某种原因,我不能在我的 MacOS 项目上做同样的事情——它创建了一个名称集合。
我读到了这个可以像这样使用的符号:
@objc(SpecialCollection)
class Collection: Realm.Object {
let items: List<ItemObject>
let name: String
let url: String
....
}
Run Code Online (Sandbox Code Playgroud)
因此,这解决了名称冲突问题。在 ObjC 中,名称会有所不同,但在 Swift 中,我不需要更改任何内容。
除了我本地的 Realm 数据库之外,这一切都很好。我有很多Collection应该重命名的对象SpecialCollection(因为 Realm 在 Swift 下使用 ObjC)。我想执行迁移来执行此操作,但显然还没有支持的方法来执行此操作?我注意到 github 上关于这个问题的票被“监视”了,但不幸的是,仍然没有已发布的解决方案来解决这个问题。
我的所有Collection对象都包含List对象(因此得名)。因此,我尝试对Collection迁移中的所有对象运行枚举......我只需要旧对象,并使用新名称创建一个新对象,如下所示:
migration.enumerateObjects(ofType: "Collection", { (oldObject, _) in
migration.create("SpecialCollection", value: oldObject)
}
Run Code Online (Sandbox Code Playgroud)
但是由于oldObject有其他对象的列表,Realm 的迁移将尝试创建任何List对象中的所有项目......这是无法完成的,因为它创建了具有相同primaryKey值的对象(导致崩溃)。
所以,我不能让旧名称(集合),我不能转换为新的名称,而我不能只垃圾桶用户的数据。所以,我真的陷入了僵局。
块引用
我尝试oldObject在创建新对象之前进行修改,但您无法oldObject在迁移中进行更改。
唯一的规则是旧数据必须保留,我不能在这里破坏用户的领域。
感谢您在这方面的任何帮助。不胜感激。
昨晚我遇到了非常相似的问题。我有几个想要重命名的 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")
Run Code Online (Sandbox Code Playgroud)
这就是我昨晚自己解决这个问题的方法,在 GitHub、SO 或其他地方的 cocoa-realm 中几乎找不到任何关于此问题的信息。上面的示例与您所要求的唯一不同之处在于您没有要求重命名 ItemObject 类。您可以尝试创建新的 ItemObject 对象并按照我在示例中显示的相同方式映射属性。我不明白为什么它不起作用。我已经提供了我的示例,准确说明了我如何解决自己的问题,因为我昨晚测试了一些迁移以证明它是可靠的。
由于你的问题已经近 5 个月了,我只是为了后代发布这个答案。希望这对某人有帮助!
在 iOS 11.3 sim / Xcode 9.3 / Swift 4.1 上使用 Realm 3.3.2 进行测试
| 归档时间: |
|
| 查看次数: |
2504 次 |
| 最近记录: |