首页 > 解决方案 > 如何执行更好的 SwiftRealm 迁移价值

问题描述

我在 iOS 和 Android 上使用 Realm Swift 和 Realm-java。我需要实现数据库迁移以更新数据库中的值。在 Swift 上,迁移按如下方式完成:currentVersion -> latestVersion。在 Android 上:v1 -> v2 -> latestVersion。

以下示例显示 iOS 上的迁移 0 -> 1 和 1 -> 2:

迁移 0 -> 1 :



    /// Function to migrate version 0 to version 1.
    /// Create Fantastic film category and associated 
    ///
    /// - Parameter migration: Migration instance.
    static func migrateFrom0To1(_ migration: Migration) {
        // Film to add for Fantastic category.
        let existingFilmToAdd: [String] = ["STAR_WARS", "HARRY_POTTER"]
        // Get stored films.
        var filmToSet: [MigrationObject] = []
        migration.enumerateObjects(ofType: Film.className()) { _, filmDb in
            let key = filmDb!["filmKey"] as! String
            if existingFilmToAdd.contains(key) {
                filmToSet.append(filmDb!)
            }
        }
        // Create Fiction Category.
        let fantasticCategory = migration.create(Category.className())
        fantasticCategory["categoryKey"] = "FANTASTIC"
        fantasticCategory["name"] = "Fantastic"
        fantasticCategory["films"] = filmToSet
    }

迁移 0/1 -> 2



    /// Function to migrate version 0 to version 1.
    /// Create Fantastic film category and associated 
    ///
    /// - Parameter migration: Migration instance.
    static func migrateFrom0To1(_ migration: Migration) {
        // Film to add for Fantastic category.
        let existingFilmToAdd: [String] = ["STAR_WARS", "HARRY_POTTER"]
        // Create Superman Film
        let superman = migration.create(Film.className())
        superman["filmKey"] = "SUPERMAN"
        superman["name"] = "Superman"
        superman["time"] = 2 
        // Get stored films.
        var filmToSet: [MigrationObject] = []
        migration.enumerateObjects(ofType: Film.className()) { _, filmDb in
            let key = filmDb!["filmKey"] as! String
            if existingFilmToAdd.contains(key) {
            filmToSet.append(filmDb!)
            }
        }
        filmToSet.append(superman)
        // Create Fiction Category.
        let fantasticCategory= migration.create(Category.className())
        fantasticCategory["categoryKey"] = "FANTASTIC"
        fantasticCategory["name"] = "Fantastic"
        fantasticCategory["films"] = filmToSet
    }
    
    /// Function to migrate version 1 to version 2.
    /// Add film in Fantastic Category 
    ///
    /// - Parameter migration: Migration instance.
    static func migrateFrom1To2(_ migration: Migration) {
        // Create Superman Film
        let superman = migration.create(Film.className())
        superman["filmKey"] = "SUPERMAN"
        superman["name"] = "Superman"
        superman["time"] = 2 
        // Get stored films.
        var filmToSet: [MigrationObject] = []
        // Update Fantastic film
        migration.enumerateObjects(ofType: Category.className()) { _, migrationCategory in
            let categoryKey = migrationMarket!["categoryKey"] as! String
            if categoryKey == "FANTASTIC" {
                let oldFilm = migrationCategory!["films"] as! List
                for film in oldFilm {
                   filmsToSet.append(film)
                }
                filmsToSet.append(superman)
                migrationCategory!["films"] = filmsToSet
            }
        }
    }

这个例子很简单,因为有简单的数据,但是当我们有更多的价值要添加和修改时,它会使迁移变得越来越复杂。

在 Android 上没有问题,迁移会一个接一个,因为在每个迁移函数结束时,数据库中的数据都是可用的。swift 上的迁移实现起来越来越复杂。

我想让 Swift 迁移像 Android 迁移一样运行。在查看文档和不同的票后,我找不到解决方案。您有解决问题的解决方案或新架构吗?

注意:该解决方案必须始终为我提供迁移数据库架构的可能性

标签: androidswiftrealmrealm-migration

解决方案


您可以使用类似的东西来迁移您的领域。

Realm.Configuration.defaultConfiguration = Realm.Configuration(schemaVersion: 2,
                                                migrationBlock: { (migration, oldSchemaVersion) in
                                                    migrate(oldScema: oldSchemaVersion, migration: migration)
                                                })

在 migrate(oldScema:, migration:) 函数中,您可以检查旧架构版本并添加相应的操作。前任:

func migrate(oldScema: Int, migration: Migration) {
    if oldScema < 1 {
        // Migrate 0 -> 1
    }

    if oldScema < 2 {
        // Migrate 1 -> 2
    }
    
    // etc for other migrations
}

推荐阅读