Surveiller l'état de l'appareil sur iOS

Dans les API Home pour iOS, l'observation des changements d'état dans la maison est possible grâce à l'utilisation du framework Combine en Swift. Vous pouvez observer les modifications apportées aux structures, aux pièces, aux métadonnées des appareils et à l'état des appareils dans les API Home avec n'importe quelle API à l'aide de HomeDevice. Pour ce faire, vous devez vous abonner aux éditeurs qui exposent les valeurs des événements asynchrones.

Lorsqu'un élément d'une collection est ajouté, supprimé ou modifié, le dernier instantané de la collection est renvoyé.

Il incombe au développeur de déduire les modifications spécifiques en comparant cet instantané avec une copie plus ancienne. Le champ id fourni pour chaque type d'objet parent dans les API Home peut être utilisé à cette fin.

Développer des objets facultatifs

Lorsqu'un objet est facultatif, utilisez if let ou guard pour le décompresser de manière sécurisée. N'utilisez pas !, car ! ne doit jamais être utilisé, sauf si le développeur sait avec certitude que l'objet ne peut pas être nul.

Dans l'exemple, le paramètre d'entrée structureID est défini comme String?, ce qui signifie qu'il s'agit d'une chaîne facultative qui peut être nulle. Cette fonction recherche l'objet Structure en fonction de l'entrée dans structureID.

Voici comment nous vous recommandons de gérer les objets facultatifs :

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

Utiliser les éditeurs

Vous trouverez ci-dessous quelques exemples de base d'utilisation des API Home avec des éditeurs. Pour les exemples suivants, une instance de Home doit être créée.

var home: Home?

Avant d'accéder aux collections, assurez-vous de les décompresser, car elles sont facultatives :

guard let home else { return nil }

Suivre les modifications apportées à une structure

Les modifications suivantes apportées à une structure déclenchent cette collecte :

  • Nom de la structure
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)")
    }
  }

Suivre les modifications apportées à un appareil spécifique

Les modifications suivantes apportées à un appareil déclenchent cette collecte :

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

Suivre les modifications apportées à un trait spécifique sur un appareil

Utilisez n'importe quel trait compatible avec l'appareil et les API Home. Pour obtenir la liste complète, consultez 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)")
    }
  }

Suivre les modifications apportées à un type spécifique sur un appareil

Les modifications suivantes apportées à un type d'appareil déclenchent cette collecte :

Utilisez n'importe quel type d'appareil Matter compatible avec les API Home. Pour obtenir la liste complète, consultez 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)")
    }
  }

Suivre les modifications apportées à une pièce dans une structure

Les modifications suivantes apportées à un salon déclenchent cette collecte :

Pour savoir quand des appareils sont ajoutés à une pièce ou en sont supprimés, utilisez la requête devices().

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

S'abonner à des événements

Dans les API Home, les événements sont utilisés pour détecter les changements d'état d'un appareil.

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