@ObservedResults always connects to the default realm

This is a followup question to a previous post I wrote here: Can't use anything other than default.realm with SwiftUI - #2 by Jay

The setup is that I have a development.realm that I use for development, and a default.realm that I use when I open the app not during development.

Following @Jay response I managed to get things updated in the development.realm, which I wasn’t doing properly before.

The problem now is that I have a bunch of views reading from the realm, and they all seem to be using default.realm.

My code looks something like this:

import RealmSwift

struct MyView: View {
    // var realm = RealmService.shared.realm // I tried adding this, just to test, but it didn't work
    @ObservedResults(SomeObject.self, where: {$0.isValid}) var validObject
    // ...
}

I guess I must be missing some initialization somewhere, but I have no clue where that could be. I’ve already gone through this other conversation, but it didn’t help my solve it: How do you change the default configuration for @ObservedResults()? - #12 by Jay

Thanks!

I am not sure there’s enough code in the question to troubleshoot the issue as we don’t know what was done with Realm before that line of code

If you don’t specify a configuration for Realm, it uses the default configuration, which would include using the default.realm file. One suggestion in a SwiftUI environment is that if you want to specify a certain file, you do that globally by defining what the defaultConfig is, and then future calls to Realm know to use that file.

For example, early in your apps code if you do this

var config = Realm.Configuration.defaultConfiguration
config.fileURL!.deleteLastPathComponent()
config.fileURL!.appendPathComponent("jays_cool")
config.fileURL!.appendPathExtension("realm")
Realm.Configuration.defaultConfiguration = config

later on, elsewhere in your app, doing this

let realm = try! Realm()
let config = realm.configuration
print(config.fileURL)

would output

.../jays_cool.realm)

that in turn would be that all proper wrappers, like @ObservedResults would use that configured realm as well.

While my solution (linked in the question) to use a singleton/global RealmService is another option, in SwiftUI you can also explicitly define the Realm configuration. Then that Realm or config can be injected as a .environment value, or even inject the .realmConfiguration instead.

So start here Open a Realm with a Configuration noting this

When you do not specify a configuration, these property wrappers use the defaultConfiguration. You can set the defaultConfiguration globally, and property wrappers across the app can use that configuration when they implicitly open a realm.

Then, in SwiftUI you can inject a realm that you opened in another SwiftUI view into a view as an environment value. The property wrapper (@ObservedResults for example) uses this passed-in realm to populate the view:

ListView().environment(\.realm, realm)

or inject the realm configuration

LocalOnlyContentView().environment(\.realmConfiguration, Realm.Configuration(some config))

Thanks for the fast response again Jay. Setting the global configuration worked.

Here’s the final singleton code in case it’s useful for someone else:

import Foundation
import RealmSwift

class RealmService {
    private init() {}

    static let shared = RealmService()

    lazy var realm: Realm = {
        var config = Realm.Configuration.defaultConfiguration

        #if DEBUG
            let developmentRealmLocation = config.fileURL!.deletingLastPathComponent().appendingPathComponent("development").appendingPathExtension("realm")

            config.fileURL = developmentRealmLocation
        #endif

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

I just had to add the line Realm.Configuration.defaultConfiguration = config once config is defined.

I’m guessing I could just call let realm = try! Realm.init() in the next line given that I’ve already set the config globally, but it’s not hurting being explicit there as well.

Thanks!

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