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
    // Error getting FanDeviceType
    return Empty<FanDeviceType, Never>().eraseToAnyPublisher()
  }
  .sink { [weak self] fanDeviceType in
    self?.fanDeviceType = fanDeviceType
    self?.updateTileInfo()
  }
}