Home > Blockchain >  Realm SwiftUI — update Schema Version
Realm SwiftUI — update Schema Version

Time:01-24

I am trying to update the Schema version, so that I can change the schema additively (just add one property without affecting existing records).

I ran the following code on load of my home screen view:

var configCheck = Realm.Configuration();
do {
    let fileUrlIs = try schemaVersionAtURL(configCheck.fileURL!)
    print("schema version \(fileUrlIs)")
} catch  {
    print(error)
}

The schema version was 0.

I then added this to the onl oad function:

 var config = Realm.Configuration.defaultConfiguration
config.schemaVersion = 2
let realm = try! Realm(configuration: config)
        
configCheck = Realm.Configuration();
do {
    let fileUrlIs = try schemaVersionAtURL(configCheck.fileURL!)
    print("schema version \(fileUrlIs)")
} catch  {
    print(error)
}

When I try to write to the database, I get this error:

RealmSwift/SwiftUI.swift:483: Fatal error: 'try!' expression unexpectedly raised an error: Error Domain=io.realm Code=1 "Provided schema version 0 is less than last set version 2." UserInfo={NSLocalizedDescription=Provided schema version 0 is less than last set version 2., Error Code=1}

2023-01-23 14:33:30.862303 0400 AppName[87285:5267261] RealmSwift/SwiftUI.swift:483: Fatal error: 'try!' expression unexpectedly raised an error: Error Domain=io.realm Code=1 "Provided schema version 0 is less than last set version 2." UserInfo={NSLocalizedDescription=Provided schema version 0 is less than last set version 2., Error Code=1}

How do I do this properly? I'm not sure what the error means, as I thought I had updated the schema version (running the original code now says schema version 2).

CodePudding user response:

I figured it out.

Create a new class RealmMigrator:

import Foundation
import RealmSwift


class RealmMigrator {
    init() {
        updateRealmSchema()
    }
    
    func updateRealmSchema() {
        var config = Realm.Configuration.defaultConfiguration
        config.schemaVersion = 2
        let realm = try! Realm(configuration: config)

        var configCheck = Realm.Configuration();
        
        Realm.Configuration.defaultConfiguration = config
        let _ = try! Realm()
        
        
        do {
             let fileUrlIs = try schemaVersionAtURL(configCheck.fileURL!)
            print("schema version \(fileUrlIs)")
        } catch  {
            print(error)
        }
    }
}

You can do more complicated migration stuff here too, see this video for example on how to amend existing records.

In the app entry point (named [AppName].swift), I added the last line here, in the body:

@main
struct AppName: App {
    var body: some Scene {
        let realmMigrator = RealmMigrator()

CodePudding user response:

While the other answer is fine, it can be greatly simplified if the only changes are additive (as indicated in the question)

In other words, if there are existing models and a property is added, the migration becomes three lines of code.

For example, if the current schema version is 4 and a property is added to a model, this is all that's needed

let config = Realm.Configuration(schemaVersion: 5)
Realm.Configuration.defaultConfiguration = config
let realm = try! Realm()

it can be called in the AppDelegate if you have one or anytime before needing Realm to update it.

  • Related