Créer une application mobile à l'aide des API Home sur iOS

1. Introduction

f154e30306882c74.png

Que sont les API Home ?

Les API Google Home fournissent un ensemble de bibliothèques permettant aux développeurs d'exploiter l'écosystème Google Home. Grâce aux API Home, les développeurs peuvent créer des applications qui mettent en service et contrôlent facilement les appareils connectés.

3e11583c779a2cec.png

Composants des API Home

Les API Home se composent des éléments suivants:

  • API Device et Structure: interagissez avec la maison d'un utilisateur. Les applications peuvent utiliser ces API pour lire des informations sur les appareils, les pièces et les structures (par exemple, consulter la température actuelle du thermostat) et contrôler les appareils (par exemple, modifier la température mémorisée du thermostat).
  • API de mise en service: mettez en service (configurez) de nouveaux appareils Matter dans le tissu avec un minimum d'efforts.
  • API Automation: créez, supprimez et interrogez les automatisations exécutées dans la maison d'un utilisateur.

Prérequis

Points abordés

  • Créer une application iOS à l'aide des API Home en suivant les bonnes pratiques
  • Utiliser les API Device et Structure pour représenter et contrôler une maison connectée
  • Utiliser l'API de configuration pour ajouter des appareils à l'écosystème Google Home
  • Utiliser l'API Automation pour créer une automatisation de base

2. Configurer votre maison

Préparer les appareils

Le Google Home Playground propose différents appareils connectés prédéfinis et émulés. Il est recommandé pour exploiter tout le potentiel des API Home, en particulier si vous disposez d'un nombre limité d'appareils chez vous.

Suivez les instructions pour vous connecter à Google Home Playground et associer votre compte dans l'application Google Home. Vous devriez alors pouvoir voir les appareils dans l'onglet "Appareils" de l'application Google Home.

c892afce113abe8f.png

3. Configuration

Obtenir le code de l'application exemple

Commencez par cloner le code source depuis GitHub:

git clone https://github.com/google-home/google-home-api-sample-app-ios.git

Le répertoire d'exemple contient deux branches, start et finished, pour cet atelier de programmation.

  • start: code de démarrage du projet, que vous allez modifier tout au long de l'atelier de programmation.
  • finished: code final de cet atelier de programmation (pour vérifier ce que vous avez fait).

Se familiariser avec le code de démarrage

Commencez cet atelier de programmation en passant à la branche start de votre dépôt cloné:

git checkout start

Cette branche contient le code de démarrage du projet. Vous allez modifier ce code tout au long de l'atelier de programmation pour implémenter toutes les fonctionnalités. L'application exemple de l'atelier de programmation fournit une structure de base créée en Swift pour interagir avec le SDK iOS des API Home. Examinons rapidement les principaux composants du projet start:

  • Main Entry (GoogleHomeAPISampleIOSApp): situé dans GoogleHomeAPISampleIOS/Main/GoogleHomeAPISampleIOS.swift, il s'agit du point d'entrée principal de l'application. Il configure et initialise le SDK, puis configure l'interface utilisateur principale.
  • Core Views (View/):
    • MainView.swift: vue racine après le lancement, contenant le NavigationView principal. Il gère la sélection de la structure Google Home active et affiche l'StructureView correspondante.
    • StructureView.swift: affiche le contenu de la structure actuellement sélectionnée. Utilise des onglets pour basculer entre une grille de appareils et la liste des automatisations. Il propose également des menus permettant d'ajouter des pièces ou des appareils.
    • DeviceView.swift: représente la carte interactive d'un seul appareil dans la grille StructureView.
    • AutomationsView.swift: affiche la liste des automatisations existantes pour la structure et permet de créer ou d'afficher les détails des automatisations.
  • ViewModels (ViewModel/): ces classes gèrent l'état et la logique des vues.
    • AccountViewModel.swift: gère la connexion à l'objet Home et gère l'état d'authentification.
    • MainViewModel.swift: gère la liste des objets Structure disponibles et suit la structure sélectionnée.
    • StructureViewModel.swift: gère l'affichage des pièces et des objets DeviceControl dans la structure sélectionnée.
    • AutomationList.swift, AutomationViewModel.swift, etc. : gère l'extraction, l'affichage, la création et la gestion des automatisations.
  • Device Controls (ViewModel/Device/):
    • DeviceControl.swift: classe de base permettant de représenter les appareils contrôlables dans l'UI.
    • Sous-classes spécifiques (LightControl.swift, FanControl.swift, OnOffPlugInUnitControl.swift, etc.): implémentez la logique de l'UI, le contrôle de l'appareil et la mise en correspondance des états pour différents types d'appareils en fonction de leurs caractéristiques.
    • DeviceControlFactory.swift: responsable de la création de la sous-classe DeviceControl appropriée pour un HomeDevice donné.
  • Commissioning (Commissioning/):
    • CommissioningManager.swift: contient la logique de gestion du flux de mise en service des appareils Matter.
  • Utilities & UX (Utils/, UX/, Storage/): contient du code d'assistance pour les éléments d'interface utilisateur (couleurs, dimensions), la gestion des erreurs, le stockage de données (SelectedStructureStorage.swift) et d'autres utilitaires.

Tout au long de cet atelier de programmation, vous trouverez des commentaires tels que TODO, ou des blocs de code et des alertes commentés dans le projet start. Elles indiquent les sections dans lesquelles vous allez ajouter ou déscommenter du code pour implémenter la fonctionnalité requise, en suivant les étapes fournies.

Créer des fichiers de configuration de déploiement Apple

Pour configurer App Attest, suivez les instructions de création de fichiers de configuration de déploiement Apple. Notez qu'après la configuration, l'application ne peut être déployée que sur un appareil physique, et non dans un simulateur.

Configurer l'authentification

Pour obtenir l'ID client OAuth et activer les API Home, commencez par vous connecter à Google Cloud, puis créez un projet ou sélectionnez-en un. Suivez ensuite la procédure indiquée pour générer l'ID client OAuth et activer les API Home, puis ajoutez votre compte à la liste d'autorisation.

Configurez le SDK

Obtenez le SDK iOS des API Home et configurez-le en vous reportant aux instructions de configuration fournies dans la section Configurer le SDK. N'oubliez pas de remplacer HOME_API_TODO_ADD_APP_GROUP par votre propre groupe d'applications.

Créer et exécuter le projet

Après avoir compilé et exécuté le projet avec la branche start, une boîte de dialogue TODO et un écran affichant "Connexion requise" devraient s'afficher. L'interaction avec les API Home sera implémentée dans les sections suivantes.

bd56b7080037e38a.png 9c0f08a3f4197a77.png

Remarque: Recherchez le code à modifier dans le projet en recherchant le texte affiché dans la boîte de dialogue. Par exemple, recherchez "À FAIRE: initialiser Home".

4. Initialisation

Initialiser la maison

Avant d'utiliser l'une des API Home pour iOS, vous devez initialiser Home dans votre application. Home est l'entrée de premier niveau du SDK et permet d'accéder à toutes les entités de la structure de l'utilisateur. Lorsque vous demandez toutes les entités d'un type particulier, l'API renvoie un objet Query qui vous permet de choisir comment recevoir les résultats. Dans GoogleHomeAPISampleIOS/Accounts/AccountViewModel.swift, supprimez le commentaire et l'alerte dans connect() pour implémenter l'initialisation de la maison.

  /// TODO: initialize Home
  /// Remove comments to initialize Home and handling permission.
  private func connect() {
    Task {
      do {
        self.home = try await Home.connect()
      } catch {
        Logger().error("Auth error: \(error).")
      }
    }
  }

Autorisation d'utiliser les API Home

L'écran d'autorisation s'affiche lorsque vous exécutez l'application. Choisissez la structure Google Home, puis sélectionnez le compte figurant sur la liste d'autorisation de votre projet Google Cloud.

47310f458c0094d9.png 4a571dbd9979a88c.png e29c75891a3a67af.png

5. Appareils et structures

Obtenir des pièces et des appareils

Dans GoogleHomeAPISampleIOS/ViewModel/StructureViewModel.swift, supprimez le commentaire et l'alerte dans getRoomsAndDevices() pour obtenir les pièces et les appareils de la structure sélectionnée avec home.rooms() et home.devices(), respectivement.

  /// TODO: get rooms and devices
  /// Remove comments to get the rooms and devices from home entry
  private func getRoomsAndDevices(){
    self.home.rooms().batched()
      .combineLatest(self.home.devices().batched())
      .receive(on: DispatchQueue.main)
      .catch { error in
        Logger().error("Failed to load rooms and devices: \(error)")
        return Just((Set<Room>(), Set<HomeDevice>()))
      }
      .map { [weak self] rooms, devices in
        guard let self = self else { return [] }
        self.hasLoaded = true
        return self.process(rooms: rooms, devices: devices)
      }
      /// receive from .map and .assign() to publisher entries
      .assign(to: &self.$entries)
  }

La fonction process() s'assure d'abord que les appareils se trouvent dans la même pièce avant de les faire interagir en tant que HomeDevices à l'aide de DeviceControl et DeviceControlFactory.

4c677c4c294e67ca.png

Remarque: Si votre appareil ne figure pas dans la DeviceControlFactory, l'état "Non compatible" s'affiche. Pour en savoir plus sur les appareils compatibles, consultez la page Types d'appareils compatibles sur iOS.

Interagir avec un appareil

Le plug outlet1 est initialement inactif lorsque vous appuyez ou balayez les appareils. Pour activer l'interaction avec elle, recherchez GoogleHomeAPISampleIOS/ViewModel/Device/OnOffPlugInUnitControl.swift, puis supprimez le commentaire et l'alerte dans la fonction primaryAction().

  /// TODO: primary action of OnOffPlug
  /// Toggles the plug; usually provided as the `action` callback on a Button.
  public override func primaryAction() {
    self.updateTileInfo(isBusy: true)
    Task { @MainActor [weak self] in
      guard
        let self = self,
        let onOffPluginUnitDeviceType = self.onOffPluginUnitDeviceType,
        let onOffTrait = onOffPluginUnitDeviceType.matterTraits.onOffTrait
      else { return }

      do {
        try await onOffTrait.toggle()
      } catch {
        Logger().error("Failed to to toggle OnOffPluginUnit on/off trait: \(error)")
        self.updateTileInfo(isBusy: false)
      }
    }
  }

La fonction primaryAction(), qui se trouve dans la classe OnOffPlugInUnitControl, active ou désactive une prise connectée ou tout appareil représenté par OnOffPluginUnitDeviceType.

D'autres exemples de commandes d'appareil sont disponibles dans GoogleHomeAPISampleIOS/ViewModel/Device.

Créer une pièce

L'API Structure permet de créer et de supprimer des pièces, ainsi que de transférer des appareils entre les pièces.

Dans GoogleHomeAPISampleIOS/ViewModel/StructureViewModel.swift, supprimez le commentaire et l'alerte dans addRoom().

  /// TODO: add room
  /// Add a new room in a given structure.
  func addRoom(name: String, structure: Structure) {
    Task {
      do {
        // The view will be updated with the values from the devices publisher.
        _ = try await structure.createRoom(name: name)
      } catch {
        Logger().error("Failed to create room: \(error)")
      }
    }
  }

Pour créer une pièce avec structure.createRoom(), accédez à l'angle supérieur gauche et sélectionnez l'icône + > Ajouter une pièce. Saisissez le nom de votre nouveau salon, puis cliquez sur "Créer un salon". La nouvelle pièce s'affiche au bout de quelques secondes.

b122ae6642b7da1c.png a45f785e1d51938e.png 7753b56cbdcff8d6.png

Déplacer l'appareil dans une autre pièce

Dans GoogleHomeAPISampleIOS/ViewModel/StructureViewModel.swift, supprimez le commentaire et l'alerte dans moveDevice().

  /// TODO: move device
  /// Move a device into a different room.
  func moveDevice(device deviceID: String, to roomID: String, structure: Structure) {
    Task {
      do {
        _ = try await structure.move(device: deviceID, to: roomID)
      } catch {
        Logger().error("Failed to move to room: \(error)")
      }
    }
  }

Pour déplacer l'appareil avec structure.move(), appuyez de manière prolongée dessus, sélectionnez "Déplacer vers une autre pièce", puis choisissez la nouvelle pièce.

f9627592af44163d.png fd126fabb454f2bf.png 813e1e23e50cd9f6.png

Supprimer une salle vide

Dans GoogleHomeAPISampleIOS/ViewModel/StructureViewModel.swift, supprimez le commentaire et l'alerte dans removeRoom().

  /// TODO: delete room
  /// Delete an empty room in a given structure.
  func removeRoom(id: String, structure: Structure) {
    Task {
      do {
        // The view will be updated with the values from the devices publisher.
        _ = try await structure.deleteRoom(id: id)
      } catch {
        Logger().error("Failed to remove room: \(error)")
      }
    }
  }

Pour supprimer une salle vide avec structure.deleteRoom(), cliquez sur l'icône en forme de poubelle à droite du nom de la salle, puis confirmez l'action. Notez que seules les salles vides peuvent être supprimées.

4f129262ad67f564.png

Remarque: Remettez l'appareil à sa place pour créer une pièce vide.

6. Mise en service

Remarque: Cette section nécessite un hub Google et un appareil Matter. Assurez-vous que le hub Google de votre structure est en ligne et accessible. Si vous ne possédez pas d'appareil Matter, essayez plutôt d'utiliser l'application Matter Virtual Device (Appareil virtuel Matter).

Ajouter un appareil Matter

L'API de mise en service permet à votre application d'ajouter de nouveaux appareils Matter à la maison et au compte Google de l'utilisateur. Vous bénéficiez ainsi d'une expérience de configuration fluide directement dans votre application.

Dans GoogleHomeAPISampleIOS/Commissioning/CommissioningManager.swift, supprimez le commentaire et l'alerte dans addMatterDevice().

  /// TODO: add Matter Device
  /// Starts the Matter device commissioning flow to add the device to the user's home.
  /// - Parameters:
  ///   - structure: The structure to add the device to.
  ///   - add3PFabricFirst: Whether to add the device to a third party fabric first.
  public func addMatterDevice(to structure: Structure, add3PFabricFirst: Bool) {
    self.isCommissioning = true

    /// pass if it's 1p or 3p commissioning
    let userDefaults = UserDefaults(
      suiteName: CommissioningManager.appGroup)
    userDefaults?.set(
    add3PFabricFirst, forKey: CommissioningUserDefaultsKeys.shouldPerform3PFabricCommissioning)

    Task {
      do {
        try await structure.prepareForMatterCommissioning()
      } catch {
        Logger().error("Failed to prepare for Matter Commissioning: \(error).")
        self.isCommissioning = false
        return
      }

      // Prepare the Matter request by providing the ecosystem name and home to be added to.
      let topology = MatterAddDeviceRequest.Topology(
        ecosystemName: "Google Home",
        homes: [MatterAddDeviceRequest.Home(displayName: structure.name)]
      )
      let request = MatterAddDeviceRequest(topology: topology)

      do {
        Logger().info("Starting MatterAddDeviceRequest.")
        try await request.perform()
        Logger().info("Completed MatterAddDeviceRequest.")
        let commissionedDeviceIDs = try structure.completeMatterCommissioning()
        Logger().info("Commissioned device IDs: \(commissionedDeviceIDs).")
      } catch let error {
        structure.cancelMatterCommissioning()
        Logger().error("Failed to complete MatterAddDeviceRequest: \(error).")
      }

      self.isCommissioning = false
    }
  }

Pour créer une pièce avec structure.prepareForMatterCommissioning(), accédez en haut à gauche et sélectionnez l'icône + > Ajouter un appareil à Google Fabric. Il utilise MatterAddDeviceRequest pour ajouter l'appareil Matter à votre pièce. Une fois la pièce et le nom de l'appareil sélectionnés, l'appareil s'affiche sur l'écran "Appareils".

adf6cbb531787aaf.png f002bd6320bc480d.png

7. Automatisation

Afficher toutes les automatisations de la structure

Appuyez sur Automatisations dans la barre de navigation inférieure. structure.listAutomations() liste toutes les automatisations de votre structure.

cc6d50f72f812c24.png

Remarque: Si vous n'avez configuré aucune automatisation de la maison, le message "Ajoutez une automatisation pour commencer" s'affiche.

Créer une automatisation

Maintenant que vous connaissez les API Device et Structure, et que vous savez ajouter un appareil, il est temps de créer une automatisation à l'aide de l'API Automation.

Dans GoogleHomeAPISampleIOS/ViewModel/Automation/AutomationsRepository.swift, supprimez le commentaire, l'alerte et l'automatisation vide dans lightAutomation().

  /// TODO: create automation
  /// - Parameter devices: devices in current selected structure
  /// - Returns: the automation object to be created
  /// This automation will turn off the light after 5 seconds.
  public func lightAutomation(devices: Set<HomeDevice>) async throws -> any DraftAutomation {
    let light = devices.first { $0.name == "light2" }
    
    guard let light else {
      Logger().error("Unable to find light device with name light2")
      throw HomeError.notFound("No devices support OnOffLightDeviceType")
    }
    
    return automation(
      name: "Turn off light after 5 seconds",
      description:
        """
        Turns off light2 after it has been on for 5 seconds.
        """
    ) {
      let onOffStarter = starter(light, OnOffLightDeviceType.self, OnOffTrait.self)
      onOffStarter
      condition {
        onOffStarter.onOff.equals(true)
      }
      delay(for: Duration.seconds(5))
      action(light, OnOffLightDeviceType.self) {
        OnOffTrait.off()
      }
    }
  }

Pour créer une automatisation qui éteint la lumière cinq secondes après son allumage, accédez à la vue "Automatisation", puis cliquez sur le bouton + Ajouter. Sélectionnez ensuite Éteindre la lumière au bout de cinq secondes. Les informations sur l'automatisation, y compris les starter, condition et action, s'affichent. Cliquez sur Enregistrer pour créer l'automatisation par structure.createAutomation().

21c1f8ea2a29134b.png 4bd36f6ed9c5f6e9.png

Remarque: Les automatisations disponibles dépendent des appareils de votre maison. Si aucune automatisation n'est disponible, essayez de renommer votre ampoule "light2".

Revenez à l'onglet "Appareils" et allumez la lumière nommée "light2". Il s'éteint automatiquement au bout de cinq secondes.

Les composants d'une automatisation sont les suivants:

  • Déclencheur:événement qui déclenche l'automatisation. Dans cet exemple, l'automatisation démarrera dès qu'une modification sera apportée à OnOffTrait.
  • Condition:permet de vérifier si l'appareil déclencheur répond à des exigences spécifiques. Dans ce cas, l'automatisation s'exécute si la lumière est allumée.
  • Action:automatisation que vous souhaitez effectuer, mais uniquement si le déclencheur répond aux exigences. Si les conditions sont remplies, le voyant s'éteint.

Pour obtenir d'autres exemples, consultez la page Exemples d'automatisations.

Supprimer une automatisation

La méthode structure.deleteAutomation() est appelée lorsque vous balayez l'écran vers la gauche sur une automatisation existante et appuyez sur l'icône de la corbeille pour la supprimer de votre structure.

dc678cd9e16f89a5.png

8. Félicitations

Félicitations ! Vous avez créé une application de maison connectée de base à l'aide des API Home pour iOS.

Ce que vous avez accompli:

  • Initialisation: vous avez connecté votre application à l'écosystème Google Home à l'aide de Home.connect().
  • Autorisations: géré l'authentification et l'autorisation des utilisateurs pour accéder aux données de la maison.
  • Appareils et structures: récupération et affichage des pièces et des appareils à l'aide de home.rooms() et home.devices().
  • Contrôle de l'appareil: interaction avec l'appareil implémentée, par exemple pour activer/désactiver l'état d'un OnOffPluginUnitDeviceType en appelant des commandes sur ses traits.
  • Gestion de la structure: fonctionnalité ajoutée pour créer des pièces (structure.createRoom()), déplacer des appareils entre des pièces (structure.move()) et supprimer des pièces vides (structure.deleteRoom()).
  • Mise en service: intégration du flux de mise en service du SDK pour ajouter de nouveaux appareils Matter (MatterAddDeviceRequest).
  • Automatisation: vous avez découvert comment lister, créer (structure.createAutomation()) et supprimer (structure.deleteAutomation()) des automatisations dans une structure.

Vous savez désormais comment tirer parti des API Home pour créer des expériences de contrôle de la maison connectée riches sur iOS.

Étapes suivantes:

  • Découvrez comment contrôler d'autres types d'appareils fournis dans l'application exemple (lumières, ventilateurs, stores, etc.).
  • Découvrez les différents traits et commandes disponibles pour différents appareils.
  • Essayez de créer des automatisations plus complexes à l'aide de différents déclencheurs, conditions et actions.
  • Pour en savoir plus sur les fonctionnalités avancées et obtenir des informations détaillées, consultez la documentation des API Home.

Bravo !