iOS でデバイスのステータスをモニタリングする

iOS 向けの Home API では、Swift の Combine フレームワークを使用して、家の状態の変化を監視できます。Home API の構造、部屋、デバイスのメタデータ、デバイスの状態の変更を監視するには、HomeDevice を使用する任意の API を使用します。これは、非同期イベントの値を公開するパブリッシャーサブスクライブすることで行われます。

コレクション内のアイテムが追加、削除、変更されると、コレクションの最新のスナップショットが返されます。

このスナップショットを古いコピーと比較して、具体的な変更を推測するのはデベロッパーの責任です。この目的には、Home API の各親オブジェクト タイプに用意されている id フィールドを使用できます。

オプション オブジェクトをラップ解除する方法

オブジェクトが省略可能な場合は、if let または guard を使用してオブジェクトを安全にアンラップします。! は使用しないでください。オブジェクトが nil にならないことを開発者が確実に把握している場合を除き、! は使用しないでください。

例の入力パラメータ structureIDString? として定義されています。つまり、省略可能な文字列で、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()
  }
}