领域迁移:将对象从一个对象移动到另一个对象

时间:2016-11-10 14:15:39

标签: swift3 realm realm-migration

我有三个对象:

class Customer: Object {
    dynamic var solution: Solution!;
    ...
}

class Solution: Object {
    dynamic var data: Data!;
    ...
}

class Data: Object {
    ...
}

现在我需要将Data对象从Solution移动到Customer,以便它变为:

class Customer: Object {
    dynamic var solution: Solution!;
    dynamic var data: Data!;
    ...
}

我不知道如何实现我的Realm Migration方法,以便一切正常,我不会丢失数据。

2 个答案:

答案 0 :(得分:2)

我使用Realm迁移示例应用程序进行了一些实验,并提出了这个潜在的解决方案:

在迁移块中,您只能通过migration对象与Realm文件进行交互。任何试图在迁移过程中直接访问Realm文件都会导致异常。

话虽这么说,但是可以对migration.enumerateObjects进行嵌套调用,引用不同的Realm模型对象类。因此,它应该只是最初枚举Customer个对象,并在每次迭代中,枚举Solution个对象以找到具有正确data值的相应对象。找到后,应该可以使用Customer对象中的数据设置Solution对象。

Realm.Configuration.defaultConfiguration = Realm.Configuration(
    schemaVersion: 1,
    migrationBlock: { migration, oldSchemaVersion in
        if (oldSchemaVersion < 1) {
            migration.enumerateObjects(ofType: Customer.className()) { oldCustomerObject, newCustomerObject in
                migration.enumerateObjects(ofType: Solution.className()) { oldSolutionObject, newSolutionObject in
                    //Check that the solution object is the one referenced by the customer
                    guard oldCustomerObject["solution"].isEqual(oldSolutionObject) else { return }
                    //Copy the data
                    newCustomerObject["data"] = oldSolutionObject["data"]
                }
            }
        }
    }
})

我觉得我需要强调的是,这些代码绝不会经过测试,并保证能够在当前状态下工作。因此,我建议您确保在预先不会错过的一些虚拟数据上对其进行彻底测试。 :)

答案 1 :(得分:0)

Swift 4,Realm 3

我必须迁移链接到另一个对象的Realm对象。我想删除显式链接并将其替换为对象ID。 TiM的解决方案让我大部分都在那里,只需要一点改进。

   var config = Realm.Configuration()
   config.migrationBlock = { migration, oldSchemaVersion in
        if oldSchemaVersion < CURRENT_SCHEMA_VERSION {

            // enumerate the first object type
            migration.enumerateObjects(ofType: Message.className()) { (oldMsg, newMsg) in 

                // extract the linked object and cast from Any to DynamicObject
                if let msgAcct = oldMsg?["account"] as? DynamicObject {

                    // enumerate the 2nd object type
                    migration.enumerateObjects(ofType: Account.className()) { (oldAcct, newAcct) in
                        if let oldAcct = oldAcct {

                             // compare the extracted object to the enumerated object
                             if msgAcct.isEqual(oldAcct) {

                                // success!
                                newMsg?["accountId"] = oldAcct["accountId"]
                            }
                        }
                    }
                }
            }
        }