In den Home APIs für iOS können Änderungen am Status im Zuhause mithilfe des
Combine-Frameworks
in Swift beobachtet werden. Änderungen an Strukturen, Räumen, Gerätemetadaten und
Gerätestatus in den Home APIs können mit jeder API mithilfe von
HomeDevice beobachtet werden. Dazu werden Publisher abonniert, die Werte aus asynchronen Ereignissen bereitstellen.
Wenn ein Element in einer Sammlung hinzugefügt, gelöscht oder geändert wird, wird der aktuelle Snapshot der Sammlung zurückgegeben.
Es liegt in der Verantwortung des Entwicklers, die spezifischen Änderungen abzuleiten, indem er diesen Snapshot mit einer älteren Kopie vergleicht. Das id Feld, das für
jeden übergeordneten Objekttyp in den Home APIs
bereitgestellt wird, kann für diesen Zweck verwendet werden.
Optionale Objekte entpacken
Wenn ein Objekt optional ist, verwenden Sie if let oder guard, um das Objekt sicher zu entpacken. Verwenden Sie nicht !, da ! nur verwendet werden sollte, wenn der Entwickler sicher ist, dass das Objekt nicht „nil“ sein kann.
Der Eingabeparameter structureID im Beispiel ist als String? definiert. Das bedeutet, dass es sich um einen optionalen String handelt, der „nil“ sein kann. Diese Funktion sucht das Structure-Objekt anhand der Eingabe in structureID.
Wir empfehlen, optionale Objekte so zu verarbeiten:
func structure(structureID: String?) -> Structure? {
guard let structureID else { return nil }
return structures.first { $0.id == structureID }
}
Publisher verwenden
Im Folgenden finden Sie einige grundlegende Beispiele für die Verwendung von Publishern in den Home APIs. Für die folgenden Beispiele muss eine Instanz von Home erstellt werden.
var home: Home?
Bevor Sie auf Sammlungen zugreifen, müssen Sie sie entpacken, da sie optional sind:
guard let home else { return nil }
Änderungen an einer Struktur verfolgen
Die folgenden Änderungen an einer Struktur lösen diese Sammlung aus:
- Strukturname
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)")
}
}
Änderungen an einem bestimmten Gerät verfolgen
Die folgenden Änderungen an einem Gerät lösen diese Sammlung aus:
- Verbindungsstatus
- Gerätename
- Raummitgliedschaft
- Die Menge der unterstützten Eigenschaften
- Die Menge der unterstützten Typen
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!")
}
}
Änderungen an einer bestimmten Eigenschaft auf einem Gerät verfolgen
Verwenden Sie eine beliebige Eigenschaft, die vom Gerät und den Home APIs unterstützt wird. Eine vollständige Liste finden Sie unter
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)")
}
}
Änderungen an einem bestimmten Typ auf einem Gerät verfolgen
Die folgenden Änderungen an einem Gerätetyp lösen diese Sammlung aus:
- Änderungen an einer beliebigen Eigenschaft innerhalb des generierten Gerätetyps
Verwenden Sie einen beliebigen Matter Gerätetyp, der von den Home APIs unterstützt wird. Eine vollständige Liste finden Sie unter
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)")
}
}
Änderungen an einem Raum in einer Struktur verfolgen
Die folgenden Änderungen an einem Raum lösen diese Sammlung aus:
Verwenden Sie die devices()
Abfrage, um zu verfolgen, wann Geräte zu einem Raum hinzugefügt oder daraus entfernt werden.
home.rooms().batched()
.sink { rooms in
print("Got a new updated set of rooms!")
for room in rooms {
print("Got room #\(room.name)")
}
}
Ereignisse abonnieren
In den Home APIs werden Ereignisse verwendet, um Änderungen am Status eines Geräts zu erkennen.
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()
}
}