Home > Mobile >  SwiftUI: react to NSManagedObject property change in SwiftUI view?
SwiftUI: react to NSManagedObject property change in SwiftUI view?

Time:04-27

I am trying to figure how to have a SwiftUI view properly react to the changes made to an NSManagedObject property.

Example:

class MyViewModel: ObservableObject {
            
    @Published var car:Car // <-- NSManagedObject
    @Published var sold:Bool = false // <-- I don't want to do this, I want to simply observe the sold property on car and not have to implement this sink logic below
    var subs = [AnyCancellable]()
    
    init(car:Car) {
        self.car = car
        self.sold = car.sold
        self.car.publisher(for: \.sold)
            .removeDuplicates()
            .receive(on: RunLoop.main)
            .sink { [weak self] sold in
                self?.sold = sold
            }
            .store(in: &subs)
    }
    
}

As an example, I have a Toggle that lets me set the sold property on the Car entity.

Toggle(isOn: Binding<Bool>(get: { model.car.sold }, set: { model.car.sold = $0 } )) {
    if model.car.sold {
        Text("ON")
    } else {
        Text("OFF")
    }
}

Toggling the control does set the sold property on the car instance, but, the Toggle label:

    if model.car.sold {
        Text("ON")
    } else {
        Text("OFF")
    }

does not update accordingly.

So, if I change the car entity as a whole, things update, if I change a property of the entity the view does not update. So then I implemented the sink logic to then set a published sold property on the model. So the sold property on the car is set by the toggle, the sink kicks in and sets the model.sold, and then the Toggle label Text does update.

How can I do away with the additional @Published var sold:Bool = false in the model and simply cause the Toggle label to react to the actual car.sold property?

CodePudding user response:

Observe Car directly, it confirms to ObservableObject, so instead of view model pass in view it like

struct CarView: View {
  @ObservedObject var car: Car
  • Related