0

I have a Core Data NSManagedObject entity Person with a Bool attribute that I generate as a NSNumber. (the "Use Scalar Type" checkbox is not used, so the Bool attribute becomes an NSNumber) I am trying to observe this attribute, employed, to control the UI.

@ObservedObject var person: Person

var body: some View {
    List {
        Section {
            HStack {
                Toggle(isOn: $person.employed) { <-- 1
                    Text("Showing employed content..")
                }
            }
        }
        if person.employed.boolValue {
            Section { } etc

I get a warning at "1" saying: Cannot convert value of type 'Binding<NSNumber?>' to expected argument type 'Binding<Bool>' How can I make use of the employed attribute as a bool without changing it to a scalar?

Note: $person.employed.boolValue would not work it seems, and I would also have to account for the optional part.

1 Answer 1

0

One possible way to do it is via a custom Binding:

Toggle("Showing employed content..", isOn: Binding<Bool>(get: {
         person.employed?.boolValue == true
      }, set: { value in
         person.employed = NSNumber(value: value)
      }))  

Now, if you prefer this to be a computed property instead, you could do something like this:

var isEmployed: Binding<Bool> {
    Binding<Bool>(get: {
        person.employed?.boolValue == true
    }, set: { value in
        person.employed = NSNumber(value: value)
    })
}

var body: some View {
    Toggle("Showing employed content..", isOn: isEmployed)
}

Also, here is a possible implementation of an extension that handles optional NSNumber backed booleans (excuse my terible naming):

extension Binding where Value == NSNumber? {
    var boolBinding: Binding<Bool> {
        Binding<Bool>(get: {
            self.wrappedValue == true
        }, set: { value in
            self.wrappedValue = NSNumber(value: value)
        })
    }
}

which can be used like this:

Toggle("Showing employed content..", isOn: $person.employed.boolBinding)
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks @Alladinian for the answer. It works great. I'd love to have this factored out to make it cleaner, but it seems the solution provided by vadian above doesn't seem to work unfortunately. I ended up fetching the NSManagedObject directly within SwiftUI: @FetchRequest(fetchRequest:Person.anyFetchRequestHere) var person: FetchedResults<Person>
@Zsolt Glad that helped you. I've updated the answer to include some more options.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.