Я пытаюсь выполнить миграцию Realm с помощью следующего кода:

let version = try! schemaVersionAtURL(Realm.Configuration.defaultConfiguration.fileURL!)
let config = Realm.Configuration(
            schemaVersion: version + 1,
            migrationBlock: { migration, oldSchemaVersion in
                if oldSchemaVersion < 1 {
                    migration.enumerateObjects(ofType: MyObject.className()) { oldObject, newObject in
                        // Here I transfer existing data to new properties
                    }
                }
        })
Realm.Configuration.defaultConfiguration = config
let _ = try! Realm()

Миграция, кажется, работает нормально, но в следующий раз, когда приложение будет перезапущено, текущая и старая версии схемы будут равны 0, несмотря на то, что миграция произошла во время первого запуска, равной 1.

Но миграция выполнена, поэтому условие if выполняется, и приложение вылетает с исключением Realm, вызванным попыткой выполнить миграцию снова.

Может ли кто-нибудь помочь мне понять, что мне не хватает? Если конфигурация устанавливает версию схемы на 1 во время миграции, почему она будет 0 при следующем перезапуске приложения?

0
Foefirelord 19 Мар 2019 в 09:02

2 ответа

Лучший ответ

Оказывается, проблема заключалась в том, что на самом деле вызывали Realm до выполнения миграции. Я забыл немного кода, который выполнял в willFinishingLaunchingWithOptions, который вызывал его.

Извлеченный урок: Только самый первый вызов Realm выполняет миграцию.

0
Foefirelord 19 Мар 2019 в 15:47

Миграция, кажется, работает нормально, но в следующий раз, когда приложение будет перезапущено, текущей и старой версиями схемы будут 0,

Это происходит, когда вы удаляете локальный файл Realm и переустанавливаете его, обычно это происходит при удалении и переустановке приложения,

Realm обрабатывает миграции автоматически, все, что нужно знать, если есть новый номер версии, который заставит файл переписать его самостоятельно с новыми правилами.


Теперь для сбойной части вы используете это, проблема со статистикой open в github

let version = try! schemaVersionAtURL(Realm.Configuration.defaultConfiguration.fileURL!)

Однако я согласен с этим комментарием.

Думаю, здесь есть две проблемы:

1- Похоже, schemaVersionAtURL() создает пустой файл, если дано URL для файла, который не существует, и он, очевидно, не должен быть делать это.
2- В Swift schemaVersionAtURL() должно быть UInt64? и просто вернуть ноль, если файл не существует, а не бросать

Я рекомендую использовать простой Int для версии, а не получать его из файла, как показано в Realm документах, schemaVersion: 1 и приращении это вручную, это позволит вам всегда видеть, на каком номере версии вы находитесь, и когда он выходит из строя, вы знаете, что сделали что-то достойное для миграции.

Теперь о той части, где вы говорите.

текущая и старая версии схемы равны 0

Когда вы переустанавливаете свое приложение, оно просто воссоздает файл с версией 0, потому что новые правила, которые ваш код реализовал для Realm, это просто новый файл, поэтому установка более низкой версии кода в коде не принесет особых результатов, однако это не рекомендуется потому что, когда вы выходите в эфир, люди не будут переустанавливать приложение, они будут обновлять его, поэтому файл Realm переносится в верхнюю версию, однако новые пользователи загружают приложение с номером версии 0, поэтому подумайте об этом больше нужно сделать изменение , а не число приращения, только чем больше, тем лучше .

0
Mohmmad S 19 Мар 2019 в 08:12