How can I get the migration to run before the app starts to run the code?

前端 未结 4 1057
野性不改
野性不改 2020-12-17 02:30

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

4条回答
  •  独厮守ぢ
    2020-12-17 02:55

    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.

    Here's what needed to be done:

    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()
            }
        }
    

    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.

    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.

    UPDATE:

    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
        }
    

提交回复
热议问题