Новая миграция Realm вызывается при установке новых приложений - PullRequest
0 голосов
/ 19 января 2020

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

Вот что я вижу.

Сценарий 1: РАБОТАЕТ ТОЧНО.

Если приложение было предварительно установлено, все работает нормально, запускается новая миграция 3, и она делает все, что должна, данные преобразуются успешно, и все работает в порядке, как и ожидалось.

Сценарий 2: ОШИБКА.

Если приложение устанавливается впервые и пользователь начинает добавлять данные, как только приложение запускается, приложение выполнит sh при следующем запуске приложения (второй раз вызывается AppDelegate). Я поместил оператор печати, и похоже, что миграция 3 запускается при втором запуске приложения, но не при первом запуске.

Сценарий 3: РАБОТАЕТ ХОРОШО после взлома.

Если приложение устанавливается впервые, но на этот раз пользователь не сразу вводит какие-либо данные, вместо этого он / она убивает приложение и затем перезапускает приложение, все работает нормально, без ошибок и ввода данных без проблем.

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

Сценарий ошибки 2:

libc ++ abi.dylib: завершение с необработанным исключением типа NSException

Любая идея, почему миграция 3 запускается при втором запуске на новом устанавливает? Это не похоже на нормальное поведение, почему оно запускается во второй раз, а не при первом запуске.

Есть мысли?

class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

            /// Migration 1:
            Realm.Configuration.defaultConfiguration = Realm.Configuration(
                schemaVersion: 1,
                migrationBlock: { migration, oldSchemaVersion in
                    if (oldSchemaVersion < 1) {
                        // configuration for schema 1
                    }
            })        
            /// Migration 2:
            Realm.Configuration.defaultConfiguration = Realm.Configuration(
                schemaVersion: 2,
                migrationBlock: { migration, oldSchemaVersion in
                    if (oldSchemaVersion < 2) {
                        // configuration for schema 2
                    }
            })
            /// Migration 3:
            Realm.Configuration.defaultConfiguration = Realm.Configuration(
                schemaVersion: 3,
                migrationBlock: { migration, oldSchemaVersion in
                    if (oldSchemaVersion < 3) {
                        // configuration for schema 3
                    }
            })
        }
    }

К вашему сведению - у меня есть печать в каждая миграция и только миграция 3 запускаются при втором запуске приложения после его первой установки.

1 Ответ

0 голосов
/ 21 января 2020

Я предвосхищу это, заявив, что он публикуется в качестве ответа, поскольку он пытается проверить, что код в вопросе работает правильно вне среды ОП.

Я взял код и добавил везде выведите операторы print, чтобы можно было легко следить за потоком кода в консоли.

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

Вот дубликат кода с некоторыми добавленными инструкциями для печати. Для меня это приложение macOS, но приложение iOS будет вести себя так же.

Функция миграции находится в AppDelegate и называется так

@NSApplicationMain
class AppDelegate: NSObject, NSApplicationDelegate {

    func applicationDidFinishLaunching(_ aNotification: Notification) {
        self.doMigrate()

, а затем function

func doMigrate() {

    print("starting schema version: \(Realm.Configuration.defaultConfiguration.schemaVersion)")

    /// Migration 1:
    Realm.Configuration.defaultConfiguration = Realm.Configuration(
        schemaVersion: 1,
        migrationBlock: { migration, oldSchemaVersion in
            print("migration 1")
            if (oldSchemaVersion < 1) {
                print(" old schema < 1, performaing migration")
                // configuration for schema 1
            }
    })

    print("schema is now: \(Realm.Configuration.defaultConfiguration.schemaVersion)")

    /// Migration 2:
    Realm.Configuration.defaultConfiguration = Realm.Configuration(
        schemaVersion: 2,
        migrationBlock: { migration, oldSchemaVersion in
            print("migration 2")
            if (oldSchemaVersion < 2) {
                print(" old schema < 2, performaing migration")
                // configuration for schema 2
            }
    })

    print("schema is now: \(Realm.Configuration.defaultConfiguration.schemaVersion)")

    /// Migration 3:
    Realm.Configuration.defaultConfiguration = Realm.Configuration(
        schemaVersion: 3,
        migrationBlock: { migration, oldSchemaVersion in
            print("migration 3")
            if (oldSchemaVersion < 3) {
                print(" old schema < 3, performaing migration")
                // configuration for schema 3
            }
    })

    print("schema is now: \(Realm.Configuration.defaultConfiguration.schemaVersion)")
}

При первом запуске, вот выходные данные, отметив, что миграция не происходит

starting schema version: 0
schema is now: 1
schema is now: 2
schema is now: 3

Когда код запускается во второй раз, выходные данные идентичны

starting schema version: 0
schema is now: 1
schema is now: 2
schema is now: 3

Даже если я добавляю или изменяю модели, добавляю или изменяю данные, вывод остается тем же самым - за исключением того, что он делает sh, потому что он нуждается в миграции, если свойство объекта удалено.

Итак, ответ таков: если вы не видите того же поведения, есть что-то еще, что влияет на структуру кода / области в вашей среде. Это работает одинаково, независимо от того, запускается он один или три раза.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...