Как получать уведомления об изменениях любого свойства 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, но это не похоже на хорошую практику. Я не хочу получать задачи на уровне пользовательского интерфейса.