홈에 새 Matter 기기 추가하기

iOS용 Home API는 Matter 허브를 사용하여 패브릭에 기기를 커미셔닝합니다. 커미셔닝 중에 앱은 명령어를 SDK로 전송한 다음 허브로 전송합니다.

Matter 기기를 커미셔닝하려면 다음 단계를 따르세요.

  1. structure.prepareForMatterCommissioning()를 사용하여 Matter 커미셔닝 요청을 준비하도록 Home APIs iOS SDK에 알립니다. 이 명령어는 다음을 실행합니다.

    • 권한이 부여되었는지 확인합니다.
    • 허브가 온라인 상태이고 연결할 수 있는지 확인합니다.
    • 진행 중인 다른 커미셔닝 세션이 없는지 확인합니다.
    do {
      try await structure.prepareForMatterCommissioning()
    } catch {
      Logger.error("Failed to prepare for Matter Commissioning: \(error).")
      return
    }
    
  2. MatterAddDeviceRequest()로 요청을 만들어 Apple의 Matter 지원 흐름을 시작합니다.

    let topology = MatterAddDeviceRequest.Topology(
      ecosystemName: "Google Home",
      homes: [MatterAddDeviceRequest.Home(displayName: structure.name)]
    )
    
    let request = MatterAddDeviceRequest(topology: topology)
    
  3. perform()를 사용하여 요청을 실행합니다. 오류가 발생하면 structure.cancelMatterCommissioning()를 사용하여 커미셔닝 요청을 취소합니다.

    do {
      Logger.info("Starting MatterAddDeviceRequest.")
      try await request.perform()
      Logger.info("Successfully 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).")
    }
    
  4. Apple Developer Console에서 App Group ID를 만들어 앱이 기기의 커미셔닝 시 MatterAddDevice 확장 프로그램과 통신할 수 있도록 합니다.

    이 그룹 ID를 사용하려면 애플리케이션 번들 식별자와 프로비저닝 프로필도 업데이트해야 합니다.

  5. 초기화할 때 그룹 식별자를 사용하도록 Home 인스턴스를 구성합니다.

    func application(_ application: UIApplication, didFinishLaunchingWithOptions
    launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
      Home.configure {
        $0.sharedAppGroup = "group.com.sample.app.commissioning"
      }
    
      return true
    }
    
  6. Apple의 iOS Matter 앱 확장 프로그램을 구현합니다.

    샘플 코드는 Apple의 MatterAddDeviceExtensionRequestHandler API의 서브클래스를 구현하는 예를 보여줍니다.

    최소한 GoogleHomeMatterCommissionerSDK 프레임워크를 확장 프로그램 타겟에 추가하고 세 가지 메서드를 재정의하여 Google Home platformHomeMatterCommissioner API를 호출합니다.

    • commissionDevice
    • rooms
    • configureDevice
    import MatterSupport
    import GoogleHomeMatterCommissionerSDK
    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 {
        Logger.info("Commission Matter device with payload: '\(onboardingPayload)'.")
    
        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()
          Logger.info("Returning \(fetchedRooms.count) fetched rooms.")
          return fetchedRooms
        } catch {
          Logger.info("Failed to fetch rooms with error: \(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 {
        Logger.info("Configure Device name: '\(name)', room: \(room?.displayName ?? "").")
        do {
          let homeMatterCommissioner = try HomeMatterCommissioner(appGroup: RequestHandler.appGroup)
          await homeMatterCommissioner.configureMatterDevice(
            deviceName: name, roomName: room?.displayName)
        } catch {
          Logger.info("Configure Device failed with error: \(error).")
        }
      }
    }