Dodawanie nowych urządzeń Matter do domu

Interfejsy Home API na iOS używają huba Matter do konfigurowania urządzenia w sieci. Podczas konfiguracji aplikacja wysyła polecenie do pakietu SDK, a następnie do huba.

Konfiguracja projektu Xcode

Zanim zaimplementujesz interfejs Commissioning API, dodaj do celów Xcode wymagane możliwości, uprawnienia i właściwości Info.plist:

Zezwolenia

W plikach .entitlements głównego celu aplikacji i rozszerzenia umieść te wpisy:

  • Zarządzanie danymi uwierzytelniającymi sieci Thread:

    <key>com.apple.developer.networking.manage-thread-network-credentials</key>
    <true/>
    

    Aby używać tego uprawnienia w kompilacji dystrybucyjnej, musisz przesłać do Apple formularz prośby o uprawnienie. Apple wymaga, aby udowodnić członkostwo w grupie Thread i potwierdzić, że router graniczny Thread ma certyfikat grupy Thread.

  • Dane sieci Wi-Fi:

    <key>com.apple.developer.networking.wifi-info</key>
    <true/>
    
  • Grupy aplikacji: dodaj udostępnioną grupę aplikacji, aby umożliwić komunikację między główną aplikacją a rozszerzeniem Matter Add Device (np. group.com.yourdomain.appgroupname). Ten identyfikator jest tworzony i rejestrowany przez dewelopera w konsoli Apple dla deweloperów i musi być zgodny z grupą aplikacji skonfigurowaną w możliwościach celu w Xcode. Google Home SDK używa tego identyfikatora w obu celach do automatycznego synchronizowania stanu konfiguracji, danych uwierzytelniających sieci i list pomieszczeń za pomocą udostępnionego kontenera UserDefaults.

Udostępnianie pęku kluczy (opcjonalne)

Jeśli rozszerzenie aplikacji musi pobierać dane uwierzytelniające lub tokeny dostępu przechowywane przez główną aplikację za pomocą UserInfo.authorizationToken(), musisz skonfigurować udostępnioną grupę dostępu do pęku kluczy zarówno dla głównej aplikacji, jak i dla celów rozszerzenia aplikacji w ich plikach plist uprawnień:

<key>keychain-access-groups</key>
<array>
    <string>$(AppIdentifierPrefix)your.shared.keychain.group</string>
</array>

Właściwości Info.plist

W pliku Info.plist głównego celu aplikacji umieść te klucze opisu:

  • Opis użycia lokalizacji:

    <key>NSLocationWhenInUseUsageDescription</key>
    <string>Your custom message explaining why location access is needed to read the current Wi-Fi SSID</string>
    
  • Usługi Bonjour: W sekcji NSBonjourServices umieść usługi wymagane do lokalnego wykrywania Matter i Thread:

    <key>NSBonjourServices</key>
    <array>
        <string>_matter._tcp</string>
        <string>_matterc._udp</string>
        <string>_matterd._udp</string>
        <string>_meshcop._udp</string>
    </array>
    
  • Opis użycia sieci lokalnej: dodaj klucz NSLocalNetworkUsageDescription z komunikatem wyjaśniającym uprawnienia do wykrywania sieci lokalnej.

Konfigurowanie urządzenia

Aby skonfigfigurować urządzenie Matter:

  1. Powiadom Home APIs iOS SDK, aby przygotować się na Matter prośby o konfigurację za pomocą structure.prepareForMatterCommissioning(). To polecenie wykona te czynności:

    • Sprawdzi, czy przyznano uprawnienia.
    • Sprawdzi, czy hub jest online i dostępny.
    • Sprawdzi, czy nie ma innej aktywnej sesji konfiguracji.
    do {
      try await structure.prepareForMatterCommissioning()
    } catch {
      // Failed to prepare for Matter Commissioning
      return
    }
    
  2. Utwórz prośbę za pomocą MatterAddDeviceRequest() aby rozpocząć proces obsługi Matter przez Apple.

    let topology = MatterAddDeviceRequest.Topology(
      ecosystemName: "Google Home",
      homes: [MatterAddDeviceRequest.Home(displayName: structure.name)]
    )
    
    let request = MatterAddDeviceRequest(topology: topology)
    
  3. Wykonaj prośbę za pomocą perform(). Jeśli wystąpi błąd, anuluj prośbę o konfigurację za pomocą structure.cancelMatterCommissioning().

    do {
      // Starting MatterAddDeviceRequest.
      try await request.perform()
      // Successfully completed MatterAddDeviceRequest.
      let commissionedDeviceIDs = try structure.completeMatterCommissioning()
      // Commissioned device IDs.
    } catch let error {
      structure.cancelMatterCommissioning()
      // Failed to complete MatterAddDeviceRequest.
    }
    
  4. Utwórz App Group ID w konsoli Apple dla deweloperów, aby umożliwić aplikacji komunikowanie się z rozszerzeniem MatterAddDevice podczas konfigurowania urządzenia.

    Aby używać tego identyfikatora grupy, musisz też zaktualizować identyfikator pakietu aplikacji i profile aprowizacji.

  5. Podczas inicjowania skonfiguruj instancję Home tak, aby używała identyfikatora grupy.

    func application(_ application: UIApplication, didFinishLaunchingWithOptions
    launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
      Home.configure {
        $0.sharedAppGroup = "group.com.sample.app.commissioning"
      }
    
      return true
    }
    
  6. Zaimplementuj rozszerzenie aplikacji Matter Matter na iOS od Apple.

    Przykładowy kod pokazuje, jak zaimplementować podklasę interfejsu API firmy Apple MatterAddDeviceExtensionRequestHandler.

    Dodaj co najmniej framework GoogleHomeMatterCommissionerSDK do celu rozszerzenia i zastąp 3 metody, aby wywołać Google Home platformHomeMatterCommissioner API.

    • commissionDevice
    • rooms
    • configureDevice
    import MatterSupport
    import GoogleHomeSDK
    import OSLog
    
    final class RequestHandler: MatterAddDeviceExtensionRequestHandler {
      // The App Group ID defined by the application to share information between the extension and main app.
      private static var appGroup = "group.com.sample.app.commissioning"
    
      ...
    
      // MARK: - Home API commissioning handlers
    
      /// Commissions a device to the Google Home ecosystem.
      /// - Parameters:
      ///   - home: The home that the device will be added to
      ///   - onboardingPayload: The payload to be sent to the Matter Commissioning SDK to commission the device.
      ///   - commissioningID: An identifier not used by the Home API SDK.
      override func commissionDevice(in home: MatterAddDeviceRequest.Home?, onboardingPayload: String, commissioningID: UUID) async throws {
        // Commission Matter device with payload.
    
        var onboardingPayloadForHub = onboardingPayload
        let homeMatterCommissioner = try HomeMatterCommissioner(appGroup: RequestHandler.appGroup)
        try await homeMatterCommissioner.commissionMatterDevice(
        onboardingPayload: onboardingPayloadForHub)
      }
    
      /// Obtains rooms from the Home Ecosystem to present to the user during the commissioning flow.
      /// - Parameter home: The home that the device will be added to.
      /// - Returns: A list of rooms if obtained from the Google Home ecosystem or an empty list if there was an error in getting them.
      override func rooms(in home: MatterAddDeviceRequest.Home?) async -> [MatterAddDeviceRequest.Room] {
        do {
          let homeMatterCommissioner = try HomeMatterCommissioner(appGroup: RequestHandler.appGroup)
          let fetchedRooms = try homeMatterCommissioner.fetchRooms()
          // Returning fetched rooms.
          return fetchedRooms
        } catch {
          // Failed to fetch rooms with error
          return []
        }
      }
    
      /// Pushes the device's configurations to the Google Home Ecosystem.
      /// - Parameters:
      ///   - name: The friendly name the user chose to set on the device.
      ///   - room: The room identifier that the user chose to put the device in.
      override func configureDevice(named name: String, in room: MatterAddDeviceRequest.Room?) async {
        // Configure Device name: room
        do {
          let homeMatterCommissioner = try HomeMatterCommissioner(appGroup: RequestHandler.appGroup)
          await homeMatterCommissioner.configureMatterDevice(
            deviceName: name, roomName: room?.displayName)
        } catch {
          // Configure Device failed with error
        }
      }
    }