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()
}
}