Cómo supervisar el estado del dispositivo en iOS

En las APIs de Home para iOS, observar los cambios de estado en la casa es posible a través del uso del framework de Combine en Swift. Observar los cambios en las estructuras, las habitaciones, los metadatos y el estado de los dispositivos en las APIs de Home se puede hacer con cualquier API que use HomeDevice. Para ello, debes suscribirte a los publicadores que exponen valores de eventos asíncronos.

Cuando se agrega, borra o modifica cualquier elemento de una colección, se muestra la instantánea más reciente de la colección.

Depende del desarrollador deducir los cambios específicos comparando esta instantánea con una copia anterior. El campo id proporcionado para cada tipo de objeto superior en las APIs de Home se puede usar para este fin.

Cómo desanidar objetos opcionales

Cuando un objeto es opcional, usa if let o guard para desenvolverlo de forma segura. No uses !, ya que nunca se debe usar, a menos que el desarrollador conozca con certeza que el objeto no puede ser nulo.!

El parámetro de entrada structureID en el ejemplo se define como String?, lo que significa que es una cadena opcional y tiene la posibilidad de ser nula. Esta función encuentra el objeto Structure según la entrada en structureID.

Te recomendamos que manejes los objetos opcionales de la siguiente manera:

func structure(structureID: String?) -> Structure? {
    guard let structureID else { return nil }
    return structures.first { $0.id == structureID }
  }

Cómo usar los publicadores

A continuación, se incluyen algunos ejemplos básicos de cómo trabajar con publicadores en las APIs de Home. Para los siguientes ejemplos, se debe crear una instancia de Home.

var home: Home?

Antes de acceder a las colecciones, asegúrate de desempaquetarlas, ya que son opcionales:

guard let home else { return nil }

Realiza un seguimiento de los cambios en una estructura

Los siguientes cambios en una estructura activan esta colección:

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

Realiza un seguimiento de los cambios en un dispositivo específico

Los siguientes cambios en un dispositivo activan esta colección:

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!")
    }
  }

Realiza un seguimiento de los cambios en un atributo específico en un dispositivo

Usa cualquier atributo compatible con el dispositivo y las APIs de Home. Para obtener una lista completa, consulta 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)")
    }
  }

Realiza un seguimiento de los cambios en un tipo específico en un dispositivo

Los siguientes cambios en un tipo de dispositivo activan esta colección:

Usa cualquier tipo de dispositivo Matter compatible con las APIs de Home. Para obtener una lista completa, consulta 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)")
    }
  }

Realiza un seguimiento de los cambios en una sala de una estructura

Los siguientes cambios en una sala activan esta colección:

Para hacer un seguimiento de cuándo se agregan o quitan dispositivos de una habitación, usa la consulta devices().

home.rooms().batched()
  .sink { rooms in
    print("Got a new updated set of rooms!")
    for room in rooms {
      print("Got room #\(room.name)")
    }
  }

Suscríbete a eventos

En las APIs de Home, los eventos se usan para detectar cambios en el estado de un dispositivo.

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