W interfejsach Home API na iOS śledzenie zmian stanu w domu jest możliwe
dzięki użyciu
frameworka Combine
w języku Swift. Śledzenie zmian w strukturach, pokojach, metadanych urządzeń i
stanie urządzeń w interfejsach Home API można przeprowadzić za pomocą dowolnego interfejsu API, używając
HomeDevice. Odbywa się to przez subskrybowanie wydawców udostępniających wartości z asynchronicznych zdarzeń.
Gdy element w kolekcji zostanie dodany, usunięty lub zmodyfikowany, zwracana jest najnowsza migawka kolekcji.
Deweloper musi samodzielnie określić konkretne zmiany, porównując tę migawkę ze starszą kopią. W tym celu można użyć pola id udostępnianego w przypadku
każdego typu obiektu nadrzędnego w interfejsach Home API.
Jak rozpakować obiekty opcjonalne
Gdy obiekt jest opcjonalny, użyj if let lub guard, aby bezpiecznie go rozpakować. Nie używaj !, ponieważ nie należy go używać, 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 znajduje obiekt Structure na podstawie danych wejściowych w structureID.
Oto jak zalecamy obsługiwać obiekty opcjonalne:
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 tych przykładów należy utworzyć instancję Home.
var home: Home?
Zanim uzyskasz dostęp do kolekcji, rozpakuj je, ponieważ są opcjonalne:
guard let home else { return nil }
Śledzenie zmian w strukturze
Ta kolekcja jest wywoływana przez te zmiany w strukturze:
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 w konkretnym urządzeniu
Ta kolekcja jest wywoływana przez te zmiany w urządzeniu:
- Stan połączenia
- Nazwa urządzenia
- Przynależność do pokoju
- 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 konkretnej cesze urządzenia
Użyj dowolnej cechy obsługiwanej przez urządzenie i interfejsy Home API. Pełną listę znajdziesz w sekcji
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 w konkretnym typie urządzenia
Ta kolekcja jest wywoływana przez te zmiany w typie urządzenia:
- Zmiany w dowolnej cesze w wygenerowanym typie urządzenia
Użyj dowolnego typu urządzenia Matter obsługiwanego przez interfejsy Home API. Pełną listę znajdziesz w sekcji
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 te zmiany w pokoju:
- Nazwa pokoju
- Przynależność do struktury
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()
}
}