Can't use anything other than default.realm with SwiftUI

I’m trying to have two different realms, a “debug.realm” file, and a “default.realm” one. The “debug” should be using while I develop, and the “default” for the release version of the app.

Following the instructions on the docs, I have this code:

var realmConfig = Realm.Configuration.defaultConfiguration
realmConfig.fileURL!.deleteLastPathComponent()
realmConfig.fileURL!.appendPathComponent("debug")
realmConfig.fileURL!.appendPathExtension("realm")
realm = try! Realm(configuration: realmConfig)
print(realm.configuration.fileURL!)

Now I go to the Application Support folder and delete all the realm files, just in case. That is:

  • default.realm.management folder
  • default.realm
  • default.realm.lockl

I run the app and I can see printed on the logs the file path as “file:///Users/…/Data/Library/Application%20Support/debug.realm”, which is the expected file.

However, in finder I see that both “debug.realm” and “default.realm” have been created. Using realm studio I can confirm that making any changes is only modifying “default.realm”.

I’m sure I’m missing something. What’s going on?

Touching Realm before setting up a config for it will cause it to create the default.realm file and then after you set up the config, create the debug.realm file.

How is realm instantiated or used before this line?

realm = try! Realm(configuration: realmConfig)

Are you using it anywhere else? Did you define a migration or attempt to do anything with it before that line?


Best practice is this

var realm = try! Realm()
var realmConfig = Realm.Configuration.defaultConfiguration

realm = try! Realm(configuration: realmConfig)


or, go with a singleton shared service approach - this uses a realm file on the desktop

class RealmService {
    private init() {}

    static let shared = RealmService()

    lazy var realm: Realm = {
        let manager = FileManager()
        let homeURL = manager.homeDirectoryForCurrentUser
        let desktopURL = homeURL.appendingPathComponent("Desktop")
        let pathToThisRealmFile = desktopURL.appendingPathComponent("desktopRealm.realm")

        var config = Realm.Configuration.defaultConfiguration
        config.fileURL = pathToThisRealmFile
        let realm = try! Realm.init(configuration: config)
        return realm
    }()
}

then to use

let realm = RealmService.shared.realm


or the old classic global function (I start my global functions with a 'g"). This uses a Realm in My Dropbox/Development folder inside the My Realm Project folder.

func gGetRealm() -> Realm? {
    do {
        let manager = FileManager()
        let homeFolder = manager.homeDirectoryForCurrentUser
        let pathToThisFolder = homeFolder.appendingPathComponent("Dropbox/Development/My Realm Project")
        let pathToThisRealmFile = pathToThisFolder.appendingPathComponent("default.realm")

        var config = Realm.Configuration.defaultConfiguration
        config.fileURL = pathToThisRealmFile
        let realm = try Realm.init(configuration: config)
        return realm

    } catch let error as NSError {
        print("Error!")
        print("  " + error.localizedDescription + "  " + String(error.code) )
        return nil
    }
}
if let maybeRealm = gGetRealm() {
   //do something with maybeRealm
}

In any of the above, note that nothing is being done with Realm until it’s ready to be used. '=Realm.init(....

2 Likes

Thanks for your reply! I changed my code to use the singleton approach and it’s working great.

I was indeed calling Realm() twice. The first time in the App’s init(), and in a service top level declaration.

The change you suggested makes sure it’s called with the right config since the app starts.

Thanks again!

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.