Monitorar o estado do dispositivo no iOS

Nas APIs Home para iOS, é possível observar mudanças no estado da casa usando o framework Combine em Swift. É possível observar mudanças em estruturas, salas, metadados de dispositivos e estado do dispositivo nas APIs Home com qualquer API usando HomeDevice. Isso é feito inscrevendo-se em editores que expõem valores de eventos assíncronos.

Quando um item em uma coleção é adicionado, excluído ou modificado, o snapshot mais recente da coleção é retornado.

Cabe ao desenvolvedor deduzir as mudanças específicas comparando este snapshot com uma cópia mais antiga. O campo id fornecido para cada tipo de objeto principal nas APIs Home pode ser usado para essa finalidade.

Como desencapsular objetos opcionais

Quando um objeto é opcional, use if let ou guard para desencapsular o objeto com segurança. Não use ! porque ele nunca deve ser usado, a menos que o desenvolvedor saiba com certeza que o objeto não pode ser nulo.!

O parâmetro de entrada structureID no exemplo é definido como String?, o que significa que é uma string opcional e que pode ser nula. Essa função encontra o objeto Structure com base na entrada em structureID.

Recomendamos que você processe objetos opcionais da seguinte forma:

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

Como usar editores

A seguir, apresentamos alguns exemplos básicos de como trabalhar com editores nas APIs Home. Para os exemplos a seguir, uma instância de Home precisa ser criada.

var home: Home?

Antes de acessar as coleções, desencapsule-as, já que são opcionais:

guard let home else { return nil }

Rastrear mudanças em uma estrutura

As seguintes mudanças em uma estrutura acionam esta coleta:

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

Rastrear mudanças em um dispositivo específico

As seguintes mudanças em um dispositivo acionam essa coleta:

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

Rastrear mudanças em uma característica específica de um dispositivo

Use qualquer característica compatível com o dispositivo e as APIs Home. Para uma lista completa, consulte 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)")
    }
  }

Rastrear mudanças em um tipo específico em um dispositivo

As seguintes mudanças em um tipo de dispositivo acionam essa coleta:

Use qualquer tipo de dispositivo Matter compatível com as APIs Home. Para conferir a lista completa, consulte 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)")
    }
  }

Rastrear mudanças em um quarto em uma estrutura

As seguintes mudanças em uma sala acionam essa coleta:

Para acompanhar quando os dispositivos são adicionados ou removidos de um ambiente, use a 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)")
    }
  }

Inscrever-se em eventos

Nas APIs Home, os eventos são usados para detectar mudanças no estado de um 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()
  }
}