W interfejsach Home API na iOS obserwowanie zmian stanu w domu jest możliwe dzięki użyciu platformy Combine w języku Swift. Obserwowanie zmian w domach, pomieszczeniach, metadanych urządzeń i stanie urządzeń w interfejsach Home API można przeprowadzić za pomocą dowolnego interfejsu API przy użyciu HomeDevice. Odbywa się to przez subskrybowanie wydawców udostępniających wartości ze zdarzeń asynchronicznych.
Gdy dowolny element w kolekcji zostanie dodany, usunięty lub zmodyfikowany, zwracana jest najnowsza migawka kolekcji.
Deweloper musi sam określić konkretne zmiany, porównując ten migawkę ze starszą kopią. W tym celu można użyć pola id udostępnionego dla każdego typu obiektu nadrzędnego w interfejsach Home API.
Jak rozpakować obiekty opcjonalne
Jeśli obiekt jest opcjonalny, użyj if let lub guard, aby bezpiecznie go rozpakować. Nie używaj operatora !, ponieważ ! nie należy go stosować, chyba że deweloper
ma pewność, że obiekt nie może mieć wartości null.
Parametr wejściowy structureID w przykładzie jest zdefiniowany jako String?, co oznacza, że jest to ciąg znaków, który jest opcjonalny i może mieć wartość null. Ta funkcja wyszukuje obiekt Structure na podstawie danych wejściowych w structureID.
Zalecamy, aby obiekty opcjonalne były obsługiwane w ten sposób:
func structure(structureID: String?) -> Structure? {
guard let structureID else { return nil }
return structures.first { $0.id == structureID }
}
Jak korzystać z wydawców
Poniżej znajdziesz kilka podstawowych przykładów pracy z wydawcami w interfejsach Home API. W przypadku poniższych przykładów należy utworzyć instancję Home.
var home: Home?
Przed uzyskaniem dostępu do kolekcji rozpakuj je, ponieważ są opcjonalne:
guard let home else { return nil }
Śledzenie zmian w strukturze
Ta kolekcja jest aktywowana przez te zmiany w strukturze:
- Nazwa struktury
home.structures().batched()
.compactMap { $0.first(where: { $0.id = myStructureID} }
.removeDuplicates()
.sink { structure in
if let structure = structure {
print("Structure \(structure.id) updated to \(structure.name)")
}
}
Śledzenie zmian na konkretnym urządzeniu
Te zmiany na urządzeniu powodują uruchomienie tej kolekcji:
- Stan połączenia
- Nazwa urządzenia
- Subskrypcja Room
- Zestaw obsługiwanych cech
- Zestaw obsługiwanych typów
home.devices().batched()
.compactMap { deviceList -> HomeDevice? in
deviceList.filter { $0.name == "Bedroom Lamp"}.first
}
.removeDuplicates()
.sink { lampDevice in
if lampDevice != nil {
print("The bedroom lamp has changed!")
}
}
Śledzenie zmian w określonej cesze na urządzeniu
Używaj dowolnej cechy obsługiwanej przez urządzenie i interfejsy Home API. Pełną listę znajdziesz w Trait.
device.types.subscribe(OnOffLightDeviceType.self)
.compactMap { $0.matterTraits.onOffTrait }
.removeDuplicates()
.sink { onOffState in
if let onOffState = onOffState {
print("Got new state update: \(onOffState.onOff)")
}
}
Śledzenie zmian określonego typu na urządzeniu
Te zmiany typu urządzenia powodują uruchomienie tej kolekcji:
- Zmiany w dowolnej cesze w ramach wygenerowanego typu urządzenia
Używaj dowolnego Mattertypu urządzenia obsługiwanego przez interfejsy Home API. Pełną listę znajdziesz w DeviceType.
device.types.subscribe(DimmableLightDeviceType.self)
.compactMap { $0.matterTraits.levelControlTrait }
.removeDuplicates()
.sink { dimmableLightDevice in
if let dimmableLightDevice = dimmableLightDevice
print("Got new state update! \(levelControlTrait.currentLevel)")
}
}
Śledzenie zmian w pokoju w strukturze
Ta kolekcja jest wywoływana przez następujące zmiany w pomieszczeniu:
Aby śledzić, kiedy urządzenia są dodawane do pokoju lub z niego usuwane, użyj devices()zapytania.
home.rooms().batched()
.sink { rooms in
print("Got a new updated set of rooms!")
for room in rooms {
print("Got room #\(room.name)")
}
}
Subskrybowanie zdarzeń
W interfejsach Home API zdarzenia służą do wykrywania zmian stanu urządzenia.
self.cancellable = self.device.types.subscribe(FanDeviceType.self)
.receive(on: DispatchQueue.main)
.catch { error in
// Error getting FanDeviceType
return Empty<FanDeviceType, Never>().eraseToAnyPublisher()
}
.sink { [weak self] fanDeviceType in
self?.fanDeviceType = fanDeviceType
self?.updateTileInfo()
}
}