如何在应用程序开始运行代码之前运行迁移? [英] How can I get the migration to run before the app starts to run the code?

查看:97
本文介绍了如何在应用程序开始运行代码之前运行迁移?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在一个快速的应用程序中使用realm.io。这是我第一次运行迁移,因为我有一个应用程序正在生产中。我更改了其中一个模型,并添加了几个额外的字段。

I'm using realm.io in a swift app. This is the first time I've had to run a migration since I have an app in production. I changed one of the models and added a couple of extra fields to it.

我按照文档中的示例进行了操作,然后引用了github repo的示例工作。我认为它可能比文档中的示例更复杂。

I followed the example in the documentation and then referenced the github repo's example when that didn't work. I assumed that it was probably more complex then what the example in the documentation was letting on.

这是我在appdelegate.swift文件中的内容:

Here's what I have in my appdelegate.swift file:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

        print ("i'm in here")
        // Override point for customization after application launch.

        // Inside your application(application:didFinishLaunchingWithOptions:)

        window = UIWindow(frame: UIScreen.mainScreen().bounds)
        window?.rootViewController = UIViewController()
        window?.makeKeyAndVisible()

        // copy over old data files for migration
        let defaultPath = Realm.Configuration.defaultConfiguration.path!
        let defaultParentPath = (defaultPath as NSString).stringByDeletingLastPathComponent

        if let v0Path = bundlePath("default-v0.realm") {
            do {
                try NSFileManager.defaultManager().removeItemAtPath(defaultPath)
                try NSFileManager.defaultManager().copyItemAtPath(v0Path, toPath: defaultPath)
            } catch {}
        }

        let config = Realm.Configuration(
            // Set the new schema version. This must be greater than the previously used
            // version (if you've never set a schema version before, the version is 0).
            schemaVersion: 1,

            // Set the block which will be called automatically when opening a Realm with
            // a schema version lower than the one set above
            migrationBlock: { migration, oldSchemaVersion in
                // We haven’t migrated anything yet, so oldSchemaVersion == 0
                if (oldSchemaVersion < 1) {
                    // Nothing to do!
                    // Realm will automatically detect new properties and removed properties
                    // And will update the schema on disk automatically
                }
        })

        // define a migration block
        // you can define this inline, but we will reuse this to migrate realm files from multiple versions
        // to the most current version of our data model
        let migrationBlock: MigrationBlock = { migration, oldSchemaVersion in
            if oldSchemaVersion < 1 {

            }

            print("Migration complete.")
        }

        Realm.Configuration.defaultConfiguration = Realm.Configuration(schemaVersion: 1, migrationBlock: migrationBlock)

        // Tell Realm to use this new configuration object for the default Realm
        Realm.Configuration.defaultConfiguration = config

        // Now that we've told Realm how to handle the schema change, opening the file
        // will automatically perform the migration
        _ = try! Realm()


        return true
    }

print 永远不会运行,我觉得很奇怪。我搞砸了什么?我假设我一定是。

The print never runs which I find strange. Am I screwing something up? I'm assuming I must be.

以下是文档所说的内容,我不确定他们是否会遗漏某些东西:

Here's what the documentation said to do, I'm not sure if they were leaving something off or not:

// Inside your application(application:didFinishLaunchingWithOptions:)

let config = Realm.Configuration(
  // Set the new schema version. This must be greater than the previously used
  // version (if you've never set a schema version before, the version is 0).
  schemaVersion: 1,

  // Set the block which will be called automatically when opening a Realm with
  // a schema version lower than the one set above
  migrationBlock: { migration, oldSchemaVersion in
    // We haven’t migrated anything yet, so oldSchemaVersion == 0
    if (oldSchemaVersion < 1) {
      // Nothing to do!
      // Realm will automatically detect new properties and removed properties
      // And will update the schema on disk automatically
    }
  })

// Tell Realm to use this new configuration object for the default Realm
Realm.Configuration.defaultConfiguration = config

// Now that we've told Realm how to handle the schema change, opening the file
// will automatically perform the migration
let realm = try! Realm()

任何想法我做错了什么?

Any ideas what I'm doing wrong?

推荐答案

这最终成了解决方案。我不能说我自己想出来因为我没有。我得到了一位名叫克莱尔的优秀工程师的出色帮助。

This ended up being the solution. I cannot say that I came up with it on my own because I didn't. I got some excellent help from a wonderful engineer named Claire at realm.

这是需要做的事情:

class RoomsViewController: UIViewController, UITableViewDelegate {

    var activeRoom = -1
    var room: Room? = nil
    var array = [Room]()

    lazy var realm:Realm = {
        return try! Realm()
    }()


    var notificationToken: NotificationToken?

    @IBOutlet weak var roomsTable: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        array = Array(realm.objects(Room.self))

        setupUI()
        // Set realm notification block
        notificationToken = realm.addNotificationBlock { [unowned self] note, realm in
            // TODO: you are going to need to update array
            self.roomsTable.reloadData()
        }
    }

这是第一个获取加载的视图控制器,它立即查询领域数据库以构建数组。根据Claire的建议,Realm是懒惰加载(或尝试过),构建数组的代码被移动到viewDidLoad方法中,而在顶部调用它之前。

This is first view controller that get's loaded and it was immediately querying the realm database to build the array. With Claire's suggestion, Realm was lazy loaded (or tried) and the code to build the array was moved into the viewDidLoad method whereas before it was called at the top.

这使得领域可以向前运行。正如您可能想象的那样,我诚实地假设视图从未加载到 AppDelegate 中加载的应用程序函数之后。但是,我猜我错了。

This allowed the realm to migration to run ahead. As you might imagine, I honestly assumed that the view never got loaded until after the application function loaded in the AppDelegate. However, I guess I was wrong.

所以,这将解决它。如果您遇到同样的问题,请试一试。

So, this will solve it. If you ever happen to run into the same problem, give this a shot.

更新:

以下是appDelegate函数现在的样子:

Here's how the appDelegate function looks now:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

        // Inside your application(application:didFinishLaunchingWithOptions:)

        let config = Realm.Configuration(
            // Set the new schema version. This must be greater than the previously used
            // version (if you've never set a schema version before, the version is 0).
            schemaVersion: 1,

            // Set the block which will be called automatically when opening a Realm with
            // a schema version lower than the one set above
            migrationBlock: { migration, oldSchemaVersion in
                // We haven’t migrated anything yet, so oldSchemaVersion == 0
                if (oldSchemaVersion < 1) {
                    migration.enumerate(Inventory.className()) { oldObject, newObject in
                        // No-op.
                        // dynamic properties are defaulting the new column to true
                        // but the migration block is still needed
                    }
                    migration.enumerate(Profile.className()) { oldObject, newObject in
                        // No-op.
                        // dynamic properties are defaulting the new column to true
                        // but the migration block is still needed
                    }
                    migration.enumerate(Room.className()) { oldObject, newObject in
                        // No-op.
                        // dynamic properties are defaulting the new column to true
                        // but the migration block is still needed
                    }
                    migration.enumerate(Box.className()) { oldObject, newObject in
                        // No-op.
                        // dynamic properties are defaulting the new column to true
                        // but the migration block is still needed
                    }
                }
        })

        // Tell Realm to use this new configuration object for the default Realm
        Realm.Configuration.defaultConfiguration = config

        // Now that we've told Realm how to handle the schema change, opening the file
        // will automatically perform the migration
        do {
            _ = try Realm()
        } catch let _ as NSError {
            // print error
        }


        return true
    }

这篇关于如何在应用程序开始运行代码之前运行迁移?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆