Live binding to a Bool variable in MongoDB Realm Object

Hello everyone,

Trying to bind a toggle Binding (swiftui) to a bool in user realm, but cannot figure it out.

Steps:

  • User logs in;
  • User realm passed to main application as user object @ObservedRealmObject **var** userRealm: User

User model has a bool field, “isVisible”, how to I create my binding var to a toggle that let’s user change it’s visibility ?

It’s seems easy, but cannot get it done.

Thank you.

Ok, I finally figure it out, even if really clunky, it works:

Created a costume binding with custom getter and setter.

 let isVisible = Binding<Bool> (
                get: {
                    self.userRealm.isVisible.value!
                },
        set: {value in
            guard let thawed = userRealm.thaw(), let realm = thawed.realm else {
                   //os_log(.error, "Error")
                   return
               }
               try! realm.write {
                   thawed.isVisible.value! = value
               }
                }
            )

If there are any other simple ideas, there are still welcome.

@Radu_Patrascu, try this…

$userRealm.wrappedValue.isVisible.toggle()

Hey Andrew,

I can wrap this in an action, but the Toggle inside SwiftUI is by default toggling it, so I would expect just to do $userRealm.isVisible.wrappedValue, but I cannot.

Could you please shared the failing code snippet (or the whole view) and the error that you’re seeing?

import SwiftUI
import RealmSwift

struct exemSwift: View {
@ObservedRealmObject var userRealm: User

var body: some View {
    Toggle(isOn: $userRealm.metricUnits.wrappedValue,
           label: {
    
            Text("Units")
                .font(.title2)
            Spacer()
        Text(userRealm.metricUnits.value! ? "Oilfield" : "Metric")
        
        }
    )
}

}

Model:
**@objcMembers** **class** User: Object, ObjectKeyIdentifiable {

**dynamic** **var** _id: String = ""

**dynamic** **var** _partition: String = ""

**dynamic** **var** isSubscribed: Bool = **false**

**let** darkMode = RealmOptional<Bool>()

**dynamic** **var** email: String = ""

**let** memberOf = RealmSwift.List<Project>()

**let** metricUnits = RealmOptional<Bool>()

**dynamic** **var** name: String? = **nil**

**dynamic** **var** selectedWellPartition: String? = **nil**

**dynamic** **var** isProjectOpen: Bool = **false**

**override** **static** **func** primaryKey() -> String? {

**return** "_id"

}

}

I couldn’t find a perfect solution (the fact that metricUnits is a RealmOptional is complicating passing it as a binding to Toggle).

Hopefully, you should at least be able to avoid the need to explicitly open a Realm transaction and using thaw() in your custom binding though. Have you tried $userRealm.wrappedValue.metricUnits.value! = value?

Tried right now, it gives :
“Cannot modify managed objects outside of a write transaction.”

I actually don’t need it to be Optional, Going to change it to Bool and come with feedback.

If it’s made non-optional then I’d expect this to work: Toggle(isOn: $userRealm.metricUnits, ...

Yep, works perfectly :slight_smile: Thank you!

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