iOS 向け Home API では、Swift の Combine フレームワークを使用して、家の状態の変化を監視できます。Home API の構造、部屋、デバイスのメタデータ、デバイスの状態の変化をモニタリングするには、HomeDevice
を使用して任意の API を使用します。これは、非同期イベントから値を公開するパブリッシャーをサブスクライブすることで行われます。
コレクション内のアイテムが追加、削除、変更されると、コレクションの最新のスナップショットが返されます。
このスナップショットと古いコピーを比較して、具体的な変更点を推測するのはデベロッパーの責任です。この目的には、Home API の各親オブジェクト タイプに用意されている id
フィールドを使用できます。
オプショナル オブジェクトをアンラップする方法
オブジェクトが省略可能な場合は、if let
または guard
を使用してオブジェクトを安全にアンラップします。!
は、オブジェクトが nil にならないことを開発者が確実に把握している場合を除き、使用すべきではありません。そのため、!
は使用しないでください。
例の入力パラメータ structureID
は String?
として定義されています。これは、省略可能で nil になる可能性がある文字列であることを意味します。この関数は、structureID
の入力に基づいて Structure
オブジェクトを検索します。
オプション オブジェクトの処理方法として、次の方法をおすすめします。
func structure(structureID: String?) -> Structure? {
guard let structureID else { return nil }
return structures.first { $0.id == structureID }
}
パブリッシャーの使用方法
以降では、Home API でパブリッシャーを操作する基本的な例をいくつか示します。次の例では、Home
のインスタンスを作成する必要があります。
var home: Home?
コレクションにアクセスする前に、コレクションは省略可能であるため、必ずアンラップしてください。
guard let home else { return nil }
構造の変更を追跡する
構造に対する次の変更は、このコレクションをトリガーします。
- ストラクチャの名前
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)")
}
}
特定のデバイスの変更を追跡する
デバイスに対する次の変更により、このコレクションがトリガーされます。
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!")
}
}
デバイスの特定のトレイトの変更を追跡する
デバイスと Home API でサポートされているトレイトを使用します。完全なリストについては、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)")
}
}
デバイスの特定のタイプの変更を追跡する
デバイスタイプの次の変更により、このコレクションがトリガーされます。
- 生成されたデバイスタイプ内の特性の変更
Home API でサポートされている Matter デバイスタイプを使用します。完全なリストについては、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)")
}
}
構造内の部屋の変更を追跡する
このコレクションは、チャットルームに対する次の変更によってトリガーされます。
デバイスが部屋に追加または削除されたタイミングを追跡するには、devices()
クエリを使用します。
home.rooms().batched()
.sink { rooms in
print("Got a new updated set of rooms!")
for room in rooms {
print("Got room #\(room.name)")
}
}
イベントに登録する
Home API では、イベントはデバイスの状態の変化を検出するために使用されます。
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()
}
}