W interfejsach API Home na iOS można obserwować zmiany stanu w domu za pomocą ramy Combine w Swift. Obserwowanie zmian w strukturach, pomieszczeniach, metadanych urządzeń i stanie urządzeń w interfejsach API Home jest możliwe za pomocą dowolnego interfejsu API, który używa HomeDevice
. Aby to zrobić, zasubskrybuj wydawców, którzy udostępniają wartości z zdarzeń asynchronicznych.
Gdy dodasz, usuniesz lub zmodyfikujesz dowolny element kolekcji, zwrócony zostanie jej najnowszy snapshot.
Deweloper musi samodzielnie określić konkretne zmiany, porównując ten snapshot z starszą kopią. W tym celu można użyć pola id
udostępnionego dla każdego typu nadrzędnego obiektu w interfejsach Home API.
Jak rozpakować opcjonalne obiekty
Jeśli obiekt jest opcjonalny, użyj wartości if let
lub guard
, aby bezpiecznie go rozpakować. Nie używaj !
, ponieważ !
nigdy nie powinno być używane, chyba że deweloper wie na pewno, że obiekt nie może być równy nil.
W tym przykładzie parametr wejściowy structureID
jest zdefiniowany jako String?
, co oznacza, że jest to opcjonalny ciąg znaków, który może być równy 0. Ta funkcja znajduje obiekt Structure
na podstawie danych wejściowych w parametrye structureID
.
Oto jak zalecamy obsługiwać opcjonalne obiekty:
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 interakcji z wydawcami w ramach interfejsu Home
API. W przypadku poniższych przykładów musisz utworzyć wystąpienie elementu Home
.
var home: Home?
Zanim uzyskasz dostęp do kolekcji, musisz je rozpakować, ponieważ są opcjonalne:
guard let home else { return nil }
Śledzenie zmian w strukturze
Ta kolekcja jest wywoływana 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 określonym urządzeniu
Ta kolekcja jest wywoływana przez te zmiany na urządzeniu:
- 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 danych dotyczących konkretnej cechy na urządzeniu
Użyj dowolnej cechy obsługiwanej przez urządzenie i interfejsy API Home. 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
Ta kolekcja jest tworzona, gdy nastąpią te zmiany typu urządzenia:
- zmiany dowolnej cechy w wygenerowanym typie urządzenia;
Użyj dowolnego typu urządzenia Matter obsługiwanego przez interfejsy API Home. 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
Te zmiany w pokoju powodują utworzenie kolekcji:
Aby śledzić, kiedy urządzenia są dodawane do pokoju lub z niego usuwane, użyj zapytania devices()
.
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 API Home zdarzenia służą do wykrywania zmian stanu urządzenia.
self.cancellable = self.device.types.subscribe(FanDeviceType.self)
.receive(on: DispatchQueue.main)
.catch { error in
Logger.error("Error getting FanDeviceType: \(error)")
return Empty<FanDeviceType, Never>().eraseToAnyPublisher()
}
.sink { [weak self] fanDeviceType in
self?.fanDeviceType = fanDeviceType
self?.updateTileInfo()
}
}