在 iOS 上监控设备状态

在适用于 iOS 的 Home API 中,通过使用 Swift 中的 Combine 框架,可以观测住宅中状态的变化。使用任何 API 都可以通过 HomeDevice 观察 Home API 中结构、房间、设备元数据和设备状态的变化。为此,您需要订阅可从异步事件中公开值的发布者。

当集合中的任何项被添加、删除或修改时,系统都会返回集合的最新快照。

开发者需要通过将此快照与旧副本进行比较来推断具体更改。为此,您可以使用 Home API 中为每种父对象类型提供的 id 字段。

如何解封可选对象

如果对象是可选的,请使用 if letguard 安全地解封装对象。请勿使用 !,因为除非开发者确定对象不能为 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()
  }
}