Ron Weasley
Ron Weasley

Reputation: 247

How to observer a property in swift ui

How to observe property value in SwiftUI. I know some basic publisher and observer patterns. But here is a scenario i am not able to implement.

class ScanedDevice: NSObject, Identifiable {

    //some variables
    var currentStatusText: String = "Pending"

}

here CurrentStatusText is changed by some other callback method that update the status.

Here there is Model class i am using

class SampleModel: ObservableObject{
    @Published  var devicesToUpdated : [ScanedDevice] = []
}

swiftui component:

struct ReviewView: View {
    @ObservedObject var model: SampleModel
    var body: some View {
        ForEach(model.devicesToUpdated){ device in
            Text(device.currentStatusText)
        }
    }
}

Here in UI I want to see the real-time status

I tried using publisher inside ScanDevice class but sure can to use it in 2 layer

Upvotes: 1

Views: 797

Answers (1)

You can observe your class ScanedDevice, however you need to manually use a objectWillChange.send(), to action the observable change, as shown in this example code.

class ScanedDevice: NSObject, Identifiable {
    var name: String = "some name"
    var currentStatusText: String = "Pending"
    
    init(name: String) {
        self.name = name
    }
}

class SampleViewModel: ObservableObject{
    @Published  var devicesToUpdated: [ScanedDevice] = []
}

struct ReviewView: View {
    @ObservedObject var viewmodel: SampleViewModel
    
    var body: some View {
        VStack (spacing: 33) {
            ForEach(viewmodel.devicesToUpdated){ device in
                HStack {
                    Text(device.name)
                    Text(device.currentStatusText).foregroundColor(.red)
                }
                Button("Change \(device.name)") {
                    viewmodel.objectWillChange.send()  // <--- here
                    device.currentStatusText = UUID().uuidString
                }.buttonStyle(.bordered)
            }
        }
        
    }
}

struct ContentView: View {
    @StateObject var viewmodel = SampleViewModel()
    
    var body: some View {
        ReviewView(viewmodel: viewmodel)
            .onAppear {
               viewmodel.devicesToUpdated = [ScanedDevice(name: "device-1"), ScanedDevice(name: "device-2")]
            }
    }
}

Upvotes: 1

Related Questions