Monitorare lo stato del dispositivo su iOS

Nelle API Home per iOS, l'osservazione delle modifiche allo stato della casa è resa possibile grazie all'utilizzo del framework Combine in Swift. L'osservazione delle modifiche alle strutture, alle stanze, ai metadati dei dispositivi e allo stato dei dispositivi nelle API Home può essere eseguita con qualsiasi API utilizzando HomeDevice. Questa operazione viene eseguita sottoscrivendo i publisher che espongono i valori degli eventi asincroni.

Quando un elemento di una raccolta viene aggiunto, eliminato o modificato, viene restituita l'ultima istantanea della raccolta.

Lo sviluppatore deve 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 decomprimere gli oggetti facoltativi

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

Il parametro di input structureID nell'esempio è definito come String?, il che significa che è una stringa facoltativa e che può essere nulla. 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 gli esempi seguenti, è necessario creare un'istanza di Home.

var home: Home?

Prima di accedere alle raccolte, assicurati di decomprimerle perché sono facoltative:

guard let home else { return nil }

Monitorare le modifiche 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 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 a un trait specifico su un dispositivo

Utilizza qualsiasi trait 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 a una stanza in 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 agli eventi

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