Как получать уведомления об изменениях любого свойства ViewModel с помощью подписчиков?

Я начинаю программировать на Swift, но пытаюсь сделать приложение хорошо, используя лучшие практики.

Приложение должно управлять мостом Philips Hue для изменения состояния освещения в доме. Он читает и отправляет http-запросы с моста Hue и должен синхронизировать их с видимыми контроллерами в моем приложении.

Объекты, полученные от моста Hue, хранятся в классе HueSession() и его подклассах и изначально сопоставляются с массивом ViewModels и отображаются на экране. Все работает хорошо до этого момента.

Затем я хочу подписаться на эти ViewModels и получать событие, когда пользователь изменяет элементы управления приложением. Это позволит мне отправить http-запрос обратно на мост Hue.

К сожалению, хотя метка на Toggle меняется правильно, я получаю только одно событие для каждого источника света при запуске приложения, например...

      false set on Lightstrip 1
false set on Hue color lamp 2
false set on Hue color lamp 1
false set on Hue lightstrip plus

Изменение состояния Toggle в моем приложении не печатает сообщение, а просто меняет текст метки Toggle: ON или OFF. Я неправильно использую раковину? Или добавление класса в массив делает его копию, а не ссылку?

ApplicationData.swift

      class ApplicationData: ObservableObject {
@Published var hueResources: HueSession
@Published var bulbs: [BulbViewModel]

    var hue = HueController()
    
    
    init(){
        bulbs = []
        hueResources = HueSession()
        
        hue.GetLightsList() {
            resources in
            if resources != nil {
                self.hueResources = resources!
                
                self.hueResources.data.map(){
                    value in
                    
                    let bulb = BulbViewModel(id: value.id)
                    bulb.name = value.metadata.name
                    bulb.isOn = value.on.on
                    
                    bulb.$isOn.sink { value in print("\(value) set on \(bulb.name)") }
                    
                    self.bulbs.append(bulb)
                }
                
            }
        }
    }

}

BulbViewModel.swift

      class BulbViewModel: ObservableObject, Identifiable {
    @Published
    var color = 250.0
    
    @Published
    var amplitude = 250.0
    
    @Published
    var isOn = false
    
    var isOnText: String {
        get {
            isOn ? "ON" : "OFF"
        }
    }
    
    @Published
    var name: String = ""
    
    @Published
    var id: String
    
    init(id: String){
        self.id = id
    }
}

BulbView.swift

      struct BulbView: View {
    @ObservedObject var bulbViewModel: BulbViewModel

    var body: some View {
        VStack{
            Text("Light: \(bulbViewModel.name)")
            Slider(value: $bulbViewModel.amplitude, in: 1...254, step: 1.0)
            Slider(value: $bulbViewModel.color, in: 153...500, step: 1.0)
            Toggle("\(bulbViewModel.isOnText)", isOn: $bulbViewModel.isOn)
        }
    }
}

Сначала я попытался подписаться на методы изменения в компонентах View, но это не похоже на хорошую практику. Я не хочу получать задачи на уровне пользовательского интерфейса.

0 ответов

Другие вопросы по тегам