Search code examples
realmswift4

Realm migration crash upgrading from multiple version


func runMigration(migration: Migration, olderVersion: UInt64, newVersion: UInt64) {
    // upgrade from version 2 to 3
        if olderVersion <= 2 && newVersion >= 3 {
            update2to3(migration)
        }

    // upgrade from version 3 to 4
        if olderVersion <= 3 && newVersion >= 4 {
            update3to4(migration)
        }
}

private func update2to3(_ migration: Migration) {
    migration.enumerateObjects(ofType: Student.className(), {oldObject, newObject in
            newObject?[“address”] = “”
        })
}

private func update3to4(_ migration: Migration) {
    migration.enumerateObjects(ofType: Student.className(), {oldObject, newObject in
            newObject?[“address”] = oldObject?["address"] ?? nil
        })
}

Example the current realm schema version is 2 and the user upgrading to latest build version 4 (skipping the version 3). The above will execute the update2to3() this method will add the address property which is added in the version 3. Then will execute the update3to4() which migrate the address property to optional/nullable property.

Can anybody tell me what's wrong with the above code? Why when the update3to4() executed it crashes because the address property doesn't exists? How come the address property doesn't exist when on update2to3() will create this property?

This is the crash error:

Terminating app due to uncaught exception 'RLMException', reason: 'Invalid property name 'address' for class 'Student'.'

NOTE: This only happen when the user upgrades from 2 to 4, but if the user upgrades from 2, 3 then 4 this error won't occurred.


Solution

  • update2to3 does not create address on oldObject (and it is not possible to do that). When upgrading directly from version 2 to 4, both update2to3 and update3to4 get version 2 oldObjects and version 4 newObjects.

    For the migrations shown in your question, the simplest fix is to just delete the migration functions entirely, as they're just repeating what Realm does automatically when new properties are added.