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 über HomeDevice
beobachtet werden. Dazu abonniert man Publisher, die Werte aus asynchronen Ereignissen bereitstellen.
Wenn ein Element in einer Sammlung hinzugefügt, gelöscht oder geändert wird, wird der letzte Snapshot der Sammlung zurückgegeben.
Es liegt am Entwickler, die spezifischen Änderungen abzuleiten, indem er diesen Snapshot mit einer älteren Kopie vergleicht. Dazu kann das Feld id
verwendet werden, das für jeden übergeordneten Objekttyp in den Home APIs bereitgestellt wird.
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 auch „nil“ sein kann. Mit dieser Funktion wird das Structure
-Objekt anhand der Eingabe in structureID
gesucht.
So empfehlen wir, mit optionalen Objekten umzugehen:
func structure(structureID: String?) -> Structure? {
guard let structureID else { return nil }
return structures.first { $0.id == structureID }
}
Verlage verwenden
Im Folgenden finden Sie einige grundlegende Beispiele für die Zusammenarbeit mit Verlagen und Webpublishern 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 Erfassung aus:
- Name der Struktur
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
- Chatroom-Mitgliedschaft
- Die unterstützten Eigenschaften
- Die 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 einem bestimmten Merkmal auf einem Gerät verfolgen
Verwenden Sie ein beliebiges Merkmal, das 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 Erfassung aus:
- Änderungen an einem beliebigen Merkmal 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 einem Gebäude verfolgen
Die folgenden Änderungen an einem Chatroom lösen diese Sammlung aus:
Wenn Sie nachverfolgen möchten, wann Geräte einem Raum hinzugefügt oder daraus entfernt werden, verwenden Sie die devices()
-Abfrage.
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
Logger.error("Error getting FanDeviceType: \(error)")
return Empty<FanDeviceType, Never>().eraseToAnyPublisher()
}
.sink { [weak self] fanDeviceType in
self?.fanDeviceType = fanDeviceType
self?.updateTileInfo()
}
}