1. 소개
Home API란 무엇인가요?
Google Home API는 개발자가 Google Home 생태계를 활용할 수 있는 라이브러리 모음을 제공합니다. 개발자는 Home API를 사용하여 스마트 홈 기기를 원활하게 커미셔닝하고 제어하는 앱을 빌드할 수 있습니다.
Home API의 구성요소
Home API는 다음으로 구성됩니다.
- Device 및 Structure API: 사용자의 홈과 상호작용합니다. 앱은 이러한 API를 사용하여 기기, 방, 구조물에 관한 정보를 읽고 (예: 현재 온도 조절기 온도 보기) 기기를 제어할 수 있습니다 (예: 온도 조절기 설정값 변경).
- Commissioning API: 최소한의 노력으로 새 Matter 기기를 Fabric에 커미셔닝 (설정)합니다.
- Automation API: 사용자의 홈에서 실행되는 자동화를 생성, 삭제, 쿼리합니다.
기본 요건
- Xcode의 최신 안정화 버전
- 홈에 구조물이 하나 이상 있는 Google 계정
- 테스트 계정으로 설정된 iOS 16.4 이상을 실행하는 iOS 기기
- 프로비저닝 프로필을 생성하기 위해 Apple 개발자 프로그램에 등록된 Apple ID
- Home API를 지원하는 Google 허브
학습할 내용
- 권장사항을 사용하여 Home API를 사용하여 iOS 앱을 빌드하는 방법
- Device 및 Structure API를 사용하여 스마트 홈을 표현하고 제어하는 방법
- Commissioning API를 사용하여 Google Home 생태계에 기기를 추가하는 방법
- Automation API를 사용하여 기본 자동화를 만드는 방법
2. 홈 설정
기기 준비
Google Home 플레이그라운드는 사전 빌드된 에뮬레이션된 다양한 스마트 홈 기기를 제공하며, 특히 집에 기기가 제한되어 있는 경우 Home API의 잠재력을 최대한 활용하는 데 권장됩니다.
안내에 따라 Google Home 플레이그라운드에 로그인하고 Google Home 앱에서 계정 연결을 완료합니다. 완료하면 Google Home 앱의 '기기' 탭에 기기가 표시됩니다.
3. 설정
샘플 앱의 코드 가져오기
먼저 GitHub에서 소스 코드를 클론합니다.
git clone https://github.com/google-home/google-home-api-sample-app-ios.git
샘플 디렉터리에는 이 Codelab의 두 가지 브랜치인 start
및 finished
가 포함되어 있습니다.
start
: 이 프로젝트의 시작 코드로, 이 코드를 변경하여 Codelab을 완료합니다.finished
: 이 Codelab의 완료 코드입니다. 작업 확인에 사용됩니다.
'시작' 코드 살펴보기
클론된 저장소의 start
브랜치로 전환하여 이 Codelab을 시작합니다.
git checkout start
이 브랜치에는 프로젝트의 시작 코드가 포함되어 있습니다. Codelab을 진행하면서 이 코드를 수정하여 전체 기능을 구현합니다. 이 Codelab 샘플 앱은 Home APIs iOS SDK와 상호작용하기 위해 Swift로 빌드된 기본 구조를 제공합니다. start
프로젝트의 주요 구성요소를 간단히 살펴보겠습니다.
Main Entry (GoogleHomeAPISampleIOSApp)
:GoogleHomeAPISampleIOS/Main/GoogleHomeAPISampleIOS.swift
에 있는 기본 앱 진입점입니다. SDK를 구성하고 초기화하며 기본 사용자 인터페이스를 설정합니다.Core Views (View/)
:MainView.swift
: 실행 후 루트 뷰로, 기본NavigationView
가 포함되어 있습니다. 활성 Google Home 구조 선택을 처리하고 해당StructureView
를 표시합니다.StructureView.swift
: 탭을 사용하여 기기 그리드와 자동화 목록 간에 전환하여 현재 선택된 구조의 콘텐츠를 표시합니다. 또한 방 또는 기기를 추가하는 메뉴도 제공합니다.DeviceView.swift
:StructureView
그리드 내 단일 기기의 양방향 카드를 나타냅니다.AutomationsView.swift
: 구조의 기존 자동화 목록을 표시하고 자동화 세부정보를 만들거나 보려면 탐색을 제공합니다.
ViewModels (ViewModel/)
: 이러한 클래스는 뷰의 상태와 로직을 관리합니다.AccountViewModel.swift
:Home
객체에 대한 연결을 처리하고 인증 상태를 관리합니다.MainViewModel.swift
: 사용 가능한Structure
객체 목록을 관리하고 선택한 구조를 추적합니다.StructureViewModel.swift
: 선택한 구조 내에서 객실 및DeviceControl
객체의 표시를 관리합니다.AutomationList.swift
,AutomationViewModel.swift
등: 자동화 가져오기, 표시, 생성, 관리를 처리합니다.
Device Controls (ViewModel/Device/)
:DeviceControl.swift
: UI에서 제어 가능한 기기를 나타내는 기본 클래스입니다.- 특정 서브클래스 (
LightControl.swift
,FanControl.swift
,OnOffPlugInUnitControl.swift
등): 트레잇에 따라 다양한 기기 유형의 UI 로직, 기기 제어, 상태 매핑을 구현합니다. DeviceControlFactory.swift
: 지정된HomeDevice
에 적절한DeviceControl
서브클래스를 만드는 역할을 합니다.
Commissioning (Commissioning/)
:CommissioningManager.swift
: Matter 기기 커미셔닝 흐름을 관리하는 로직을 포함합니다.
Utilities & UX (Utils/, UX/, Storage/)
: UI 요소 (색상, 크기), 오류 처리, 데이터 저장소 (SelectedStructureStorage.swift
) 및 기타 유틸리티의 도우미 코드를 포함합니다.
이 Codelab에서는 start
프로젝트 내에 TODO
와 같은 주석이나 주석 처리된 코드 블록 및 알림을 확인할 수 있습니다. 이러한 섹션은 제공된 단계에 따라 필요한 기능을 구현하기 위해 코드를 추가하거나 주석 처리를 해제할 섹션을 표시합니다.
Apple 배포 구성 파일 만들기
App Attest를 구성하려면 Apple 배포 구성 파일 만들기에 관한 안내를 따르세요. 설정 후에는 앱을 시뮬레이터가 아닌 실제 기기에만 배포할 수 있습니다.
인증 설정
OAuth 클라이언트 ID를 가져오고 Home API를 사용 설정하려면 먼저 Google Cloud에 로그인하고 새 프로젝트를 만들거나 기존 프로젝트를 선택합니다. 그런 다음 제공된 단계에 따라 OAuth 클라이언트 ID를 생성하고 Home API를 사용 설정하고 계정을 허용 목록에 추가합니다.
SDK 설정
Home APIs iOS SDK를 가져와 SDK 설정에 제공된 설정 안내에 따라 구성합니다. HOME_API_TODO_ADD_APP_GROUP
를 자체 앱 그룹으로 바꿔야 합니다.
프로젝트 빌드 및 실행
start
브랜치로 프로젝트를 빌드하고 실행하면 TODO
대화상자와 '로그인 필요'라는 메시지가 표시된 화면이 표시됩니다. Home API 상호작용은 다음 섹션에서 구현됩니다.
참고: 프로젝트에서 대화상자에 표시된 텍스트를 검색하여 수정해야 하는 코드를 찾습니다. 예를 들어 'TODO: initialize Home'을 검색합니다.
4. 초기화
홈 초기화
iOS용 Home API를 사용하기 전에 앱에서 Home
를 초기화해야 합니다. Home
는 SDK의 최상위 항목으로, 사용자 구조의 모든 항목에 대한 액세스를 제공합니다. 특정 유형의 모든 항목을 요청하면 API는 결과를 수신하는 방법을 선택할 수 있는 Query
객체를 반환합니다. GoogleHomeAPISampleIOS/Accounts/AccountViewModel.swift
에서 connect()
의 주석과 알림을 삭제하여 홈 초기화를 구현합니다.
/// 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).")
}
}
}
Home API를 사용할 권한
앱을 실행하면 동의 화면이 표시됩니다. Google Home 구조를 선택하고 Google Cloud 프로젝트의 허용 목록에 있는 계정을 선택합니다.
5. 기기 및 구조
방 및 기기 가져오기
GoogleHomeAPISampleIOS/ViewModel/StructureViewModel.swift
에서 getRoomsAndDevices()
의 주석과 알림을 삭제하여 선택한 구조물의 방과 기기를 각각 home.rooms()
및 home.devices()
로 가져옵니다.
/// 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)
}
process()
함수는 먼저 기기가 같은 방에 있는지 확인한 다음 DeviceControl
및 DeviceControlFactory
를 사용하여 기기가 HomeDevices
로 상호작용하도록 합니다.
참고: 기기가 DeviceControlFactory
에 표시되지 않으면 '지원되지 않음'으로 표시됩니다. 지원되는 기기에 관한 자세한 내용은 iOS에서 지원되는 기기 유형 페이지를 참고하세요.
기기와 상호작용
플러그 outlet1
는 처음에는 기기를 탭하거나 스와이프할 때 비활성 상태입니다. 상호작용을 사용 설정하려면 GoogleHomeAPISampleIOS/ViewModel/Device/OnOffPlugInUnitControl.swift
를 찾아 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)
}
}
}
OnOffPlugInUnitControl
클래스 내에 있는 primaryAction()
함수는 스마트 플러그 또는 OnOffPluginUnitDeviceType
로 표현되는 기기의 켜기/끄기 상태를 전환합니다.
추가 기기 제어 예는 GoogleHomeAPISampleIOS/ViewModel/Device
에서 확인할 수 있습니다.
새 방 만들기
Structure API를 사용하면 방을 생성 및 삭제하고 방 간에 기기를 전송할 수 있습니다.
GoogleHomeAPISampleIOS/ViewModel/StructureViewModel.swift
에서 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)")
}
}
}
structure.createRoom()
로 새 방을 만들려면 왼쪽 상단으로 이동하여 '+' 아이콘 > 방 추가를 선택합니다. 새 채팅방 이름을 입력하고 '채팅방 만들기'를 클릭합니다. 몇 초 후 새 방이 표시됩니다.
기기를 다른 방으로 이동하기
GoogleHomeAPISampleIOS/ViewModel/StructureViewModel.swift
에서 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)")
}
}
}
structure.move()
를 사용하여 기기를 재배치하려면 기기를 길게 누른 다음 '다른 방으로 이동'을 선택하고 새 방을 선택합니다.
비어 있는 회의실 삭제하기
GoogleHomeAPISampleIOS/ViewModel/StructureViewModel.swift
에서 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)")
}
}
}
structure.deleteRoom()
로 빈 방을 삭제하려면 방 이름 오른쪽에 있는 휴지통 아이콘을 클릭하고 작업을 확인합니다. 빈 방만 삭제할 수 있습니다.
참고: 기기를 다시 옮겨 빈 방을 만듭니다.
6. 커미셔닝
참고: 이 섹션을 사용하려면 Google 허브와 Matter 기기가 필요합니다. 구조물의 Google 허브가 온라인 상태이고 연결할 수 있는지 확인합니다. Matter 기기가 없는 경우 Matter 가상 기기 앱을 대신 사용해 보세요.
Matter 기기 추가
Commissioning API를 사용하면 앱에서 사용자의 홈 및 Google 계정에 새 Matter 기기를 추가할 수 있습니다. 이렇게 하면 앱 내에서 바로 원활한 설정 환경을 제공할 수 있습니다.
GoogleHomeAPISampleIOS/Commissioning/CommissioningManager.swift
에서 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
}
}
structure.prepareForMatterCommissioning()
로 새 공간을 만들려면 왼쪽 상단으로 이동하여 '+' 아이콘 > Google Fabric에 기기 추가를 선택합니다. MatterAddDeviceRequest
를 사용하여 Matter 기기를 방에 추가합니다. 방과 기기 이름을 선택하면 기기가 '기기' 화면에 표시됩니다.
7. 자동화
구조의 모든 자동화 보기
하단 탐색 메뉴에서 자동화를 탭합니다. structure.listAutomations()
를 사용하여 구조의 모든 자동화가 표시됩니다.
참고: 홈 자동화가 설정되어 있지 않으면 '시작하려면 자동화를 추가하세요'라는 메시지가 표시됩니다.
자동화 만들기
이제 Device API 및 Structure API를 숙지하고 새 기기를 추가했으므로 Automation API를 사용하여 새 자동화를 만들어 보겠습니다.
GoogleHomeAPISampleIOS/ViewModel/Automation/AutomationsRepository.swift
에서 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()
}
}
}
조명이 켜진 후 5초 후에 조명을 끄는 자동화를 만들려면 자동화 뷰로 이동하여 '+ 추가' 버튼을 클릭합니다. 그런 다음 '5초 후에 조명 끄기'를 선택합니다. starter
, condition
, action
를 비롯한 자동화 세부정보가 표시됩니다. '저장'을 클릭하여 structure.createAutomation()
로 자동화를 만듭니다.
참고: 사용할 수 있는 자동화는 홈에 있는 기기에 따라 다릅니다. 사용 가능한 자동화가 표시되지 않으면 조명 기기의 이름을 'light2'로 바꿔 보세요.
'기기' 탭으로 돌아가서 'light2'라는 조명을 켭니다. 5초 후에 자동으로 꺼집니다.
자동화의 구성요소는 다음과 같습니다.
- 시작 조건: 자동화를 시작하는 이벤트입니다. 이 예에서는
OnOffTrait
에 변경사항이 있으면 자동화가 시작됩니다. - 조건: 시작 기기가 특정 요구사항을 충족하는지 확인합니다. 이 경우 조명이 켜지면 자동화가 실행됩니다.
- 작업: 시작 조건이 요구사항을 충족하는 경우에만 실행할 자동화입니다. 조건이 충족되면 조명이 꺼집니다.
추가 예시는 자동화 예시 페이지를 참고하세요.
자동화 삭제
structure.deleteAutomation()
메서드는 기존 자동화를 왼쪽으로 스와이프하고 휴지통 아이콘을 탭하여 구조에서 삭제할 때 호출됩니다.
8. 축하합니다
축하합니다. iOS용 Home API를 사용하여 기본 스마트 홈 앱을 빌드했습니다.
달성한 목표:
- 초기화:
Home.connect()
를 사용하여 앱을 Google Home 생태계에 연결했습니다. - 권한: 홈 데이터에 액세스하기 위한 사용자 인증 및 승인을 처리했습니다.
- 기기 및 구조:
home.rooms()
및home.devices()
를 사용하여 방과 기기를 가져와 표시했습니다. - 기기 제어: 트레잇에서 명령을 호출하여
OnOffPluginUnitDeviceType
의 상태를 전환하는 등 기기 상호작용을 구현했습니다. - 구조 관리: 새 방 만들기 (
structure.createRoom()
), 방 간에 기기 이동 (structure.move()
), 빈 방 삭제 (structure.deleteRoom()
) 기능이 추가되었습니다. - 구성: 새 Matter 기기 (
MatterAddDeviceRequest
)를 추가하기 위해 SDK의 구성 흐름을 통합했습니다. - 자동화: 구조 내에서 자동화를 나열하고, 만들고 (
structure.createAutomation()
), 삭제하는 (structure.deleteAutomation()
) 방법을 살펴봤습니다.
이제 Home API를 활용하여 iOS에서 풍부한 스마트 홈 제어 환경을 빌드하는 방법을 기본적으로 이해했습니다.
다음 단계:
- 샘플 앱에 제공된 다른 기기 유형 (조명, 팬, 블라인드 등)을 제어하는 방법을 살펴봅니다.
- 다양한 기기에서 사용할 수 있는 다양한 트레잇과 명령어를 자세히 살펴보세요.
- 다양한 시작 조건, 조건, 작업을 사용하여 더 복잡한 자동화를 만들어 실험해 보세요.
- 고급 기능 및 세부정보는 Home API 문서를 참고하세요.
잘하셨습니다.