Brandon Bradley
Brandon Bradley

Reputation: 3378

How to Use BindingConvertible in SwiftUI?

When Core Data creates an NSManagedObject Subclass it converts String attributes into something like @NSManaged public var name: String? (edited)

But when trying to use name in a SwiftUI TextField you run into a problem:

@Binding var entry: Entry
TextField($entry.name)

Won't build, with the following error:

'Binding< String?>' is not convertible to 'Binding< String>'

So I tried to use BindingConvertible to fix the error:

extension Optional: BindingConvertible where Wrapped == String {
    public var binding: Binding<String> {
        let boundVal = Binding(getValue: , setValue: )
        return boundVal
}

But I'm not sure what to put in the getValue: , setValue: part of the initializer and was unable to find any answer in the docs or elsewhere.

Ideally if the unwrapped String were nil the Binding would receive an empty string otherwise it would receive the value. For setting, if the field's value is an empty String, name should remain nil, otherwise it's unwrapped value should be the contents of the TextField. Any idea as to how to make this work?

Upvotes: 1

Views: 1169

Answers (1)

rob mayoff
rob mayoff

Reputation: 385540

You said “it converts String attributes into something like @NSManaged public var name: String”, but based on the error, it converts to @NSManaged public var name: String?.

If you don't want to turn off the “Optional” setting for name in your data model, then you can add a non-optional accessor to Entry like this:

extension Entry {
    var nameNonOptional: String {
        get { name ?? "" }
        set { name = newValue.isEmpty ? nil : newValue }
    }
}

and then you can bind to the new accessor:

TextField($entry.nameNonOptional)

Upvotes: 2

Related Questions