Monitorar o estado do dispositivo no iOS

Nas APIs Home para iOS, a observação de mudanças de estado na casa é feita possível com o uso da estrutura Combine no Swift. A observação de mudanças em estruturas, cômodos, metadados e estado de dispositivos nas APIs Home pode ser feita 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 esse snapshot com uma cópia mais antiga. O campo id fornecido para cada tipo de objeto pai nas APIs Home pode ser usado para essa finalidade.

Como desembrulhar objetos opcionais

Quando um objeto é opcional, use if let ou guard para desembrulhar o objeto com segurança. Não use ! porque ! 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 pode ser nula. Essa função encontra o objeto Structure com base na entrada em structureID.

Recomendamos que você processe objetos opcionais da seguinte maneira:

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

Como usar editores

A seguir, 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, desembrulhe-as, já que elas são opcionais:

guard let home else { return nil }

Acompanhar mudanças em uma estrutura

As seguintes mudanças em uma estrutura acionam essa coleção:

  • Nome da estrutura
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)")
    }
  }

Acompanhar mudanças em um dispositivo específico

As seguintes mudanças em um dispositivo acionam essa coleção:

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

Acompanhar mudanças em uma característica específica em 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)")
    }
  }

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

As seguintes mudanças em um tipo de dispositivo acionam essa coleção:

Use qualquer tipo de dispositivo Matter compatível com as APIs Home. Para uma 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)")
    }
  }

Acompanhar mudanças em um cômodo em uma estrutura

As seguintes mudanças em um cômodo acionam essa coleção:

Para acompanhar quando os dispositivos são adicionados ou removidos de um cômodo, use a devices() consulta.

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