Monitorare lo stato del dispositivo su iOS

Nelle API Home per iOS, l'osservazione delle modifiche dello stato della casa è resa possibile tramite l'utilizzo del framework Combine in Swift. È possibile osservare le modifiche a strutture, stanze, metadati dei dispositivi e stato dei dispositivi nelle API Home con qualsiasi API che utilizza HomeDevice. Per farlo, abbonati ai publisher che mostrano i valori degli eventi asincroni.

Quando un elemento di una raccolta viene aggiunto, eliminato o modificato, viene restituito l'ultimo snapshot della raccolta.

Spetta allo sviluppatore dedurre le modifiche specifiche confrontando questa istantanea con una copia precedente. A questo scopo, puoi utilizzare il campo id fornito per ogni tipo di oggetto principale nelle API Home.

Come scompattare gli oggetti facoltativi

Quando un oggetto è facoltativo, utilizza if let o guard per scomporlo in sicurezza. Non utilizzare ! perché non deve mai essere utilizzato, a meno che lo sviluppatore non sappia con certezza che l'oggetto non può essere null.!

Il parametro di input structureID nell'esempio è definito come String?, il che significa che è una stringa facoltativa e ha la possibilità di essere null. Questa funzione trova l'oggetto Structure in base all'input in structureID.

Ecco come ti consigliamo di gestire gli oggetti facoltativi:

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

Come utilizzare i publisher

Di seguito sono riportati alcuni esempi di base di utilizzo dei publisher nelle API Home. Per i seguenti esempi, è necessario creare un'istanza di Home.

var home: Home?

Prima di accedere alle raccolte, assicurati di estrarle, poiché sono facoltative:

guard let home else { return nil }

Monitorare le modifiche apportate a una struttura

Le seguenti modifiche a una struttura attivano questa raccolta:

  • Nome della struttura
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)")
    }
  }

Monitorare le modifiche apportate a un dispositivo specifico

Le seguenti modifiche a un dispositivo attivano questa raccolta:

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

Monitorare le modifiche apportate a un tratto specifico su un dispositivo

Utilizza qualsiasi tratto supportato dal dispositivo e dalle API Home. Per un elenco completo, 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)")
    }
  }

Monitorare le modifiche a un tipo specifico su un dispositivo

Le seguenti modifiche a un tipo di dispositivo attivano questa raccolta:

Utilizza qualsiasi tipo di dispositivo Matter supportato dalle API Home. Per un elenco completo, 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)")
    }
  }

Monitorare le modifiche apportate a una camera di una struttura

Le seguenti modifiche a una stanza attivano questa raccolta:

Per monitorare quando i dispositivi vengono aggiunti o rimossi da una stanza, utilizza la devices() query.

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

Iscriversi a eventi

Nelle API Home, gli eventi vengono utilizzati per rilevare le modifiche dello stato di 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()
  }
}