구조 API는 iOS용 Home API를 통해 액세스할 수 있습니다.
구조 API를 사용하려면 먼저 GoogleHomeSDK 패키지를 앱으로 가져옵니다.
import GoogleHomeSDK
오류 처리
Home API의 일부 메서드는
HomeError를 발생시키므로 do-catch 블록을 사용하여 이러한 호출에서
HomeError를 포착하는 것이 좋습니다.
HomeError를 처리할 때는 code 및 message
필드를 확인하여 무엇이 잘못되었는지 알아보세요.
처리되지 않은 오류가 있으면 앱이 비정상 종료됩니다.
자세한 내용은 오류 처리를 참고하세요.
구조 API
Home은 Home 그래프를 나타내며 구조 API의 진입점입니다.
구조, 방, 기기에 대한 참조를 제공합니다.
Structure는 Home 그래프의 구조를 나타냅니다. id 및 name과 같은 구조 메타데이터에 대한 액세스를 제공합니다.
structures()를 사용하여 계정의 모든 구조를 가져옵니다. 구조는 데이터 사용 방법을 선택할 수 있는
Query 형식으로 반환됩니다.
| API | 설명 |
|---|---|
stream() |
변경사항이 발생할 때 각 객체를 개별적으로 내보내는 Publisher를 반환합니다. |
batched() |
현재 결과를 객체의 Set으로 내보내는 Publisher를 반환합니다. 내보내진 각 Set은 객체 그래프의 현재 상태를 나타냅니다. |
list() |
현재 결과를 객체의 Set으로 반환합니다. |
structures().list() 호출은 유효한 구조 집합을 즉시 반환하지 않을 수 있습니다. 앱이 반응형이고 UI를 구동하기 위해 모든 구조 변경사항을 구독하는 stream()을 호출하는 경우 결국 유효한 구조 목록이 반환됩니다. 사용자의 휴대전화 연결이 끊어지거나 사용자가 앱에 대한 권한을 취소하는 경우와 같이 빈 구조 목록이 반환될 수 있는 다른 상황도 있습니다. 앱에서 이러한 사례를 처리해야 합니다.
@Published public private(set) var structures: [Structure] = []
private var structuresCancellable: AnyCancellable?
self.structuresCancellable = home
.structures()
.batched()
.receive(on: DispatchQueue.main)
.map { Array($0) }
.catch {
// Failed to load structures
return Just([Structure]())
}
.assign(to: \.structures, on: self)
샘플 구조 호출
구조 집합 가져오기
Query<Structure>에서 list()를 호출하면 가장 최근의
요소 집합이 반환됩니다.
// Get a stream of all structures accessible to the user let allStructuresChanges = self.home.structures() let allStructures = try? await allStructuresChanges.list()
반응형 앱을 설계할 때는 list() 대신 batched() 및 stream() 호출을 사용하는 것이 좋습니다. 이러한 호출은 홈 그래프가 변경될 때 데이터를 자동으로 생성하기 때문입니다.
구조 속성 가져오기
구조 목록을 사용하여 구조의 속성에 액세스할 수 있습니다.
// Get a stream of changes taking place on a structure. let structureChanges = try await home.structures().list().filter { $0.id == structureID } // Get a snapshot of the structure. let structure = structureChanges.first! // Get structure properties print("id \(structure.id) ") print("name \(structure.name) ")
이름으로 구조 찾기
구조의 이름을 알고 있는 경우 name 속성을 사용하여 구조에 액세스할 수도 있습니다.
do { structure1 = try await home.structures().list().first(where: { $0.name == "Main House" }) } catch let _ as HomeError { // Code for handling the exception }
여기에서 각 구조의 속성, 방, 기기에 액세스할 수 있습니다.
여러 구조 작업
둘 이상의 구조를 사용하려면 각 구조에 대한 별도의 참조를 가져옵니다.
var structure1: Structure! var structure2: Structure! do { structure1 = try await home.structures().list().first(where: { $0.name == "Main House" }) } catch let _ as HomeError { // Code for handling the exception } do { structure2 = try await home.structures().list().first(where: { $0.name == "Guest Cottage" }) } catch let _ as HomeError { // Code for handling the exception }
Rooms
방에는 기기 그룹이 포함됩니다. 방은 항상 구조의 일부이며 구조에는 여러 방이 있을 수 있습니다. 구조에서 방을 삭제해도 해당 방의 기기가 구조에서 삭제되지는 않습니다. 하지만 방이 삭제되면 해당 방의 기기가 할당 해제됩니다.
Home.rooms()를 사용하여 계정의 모든 방을 가져온 다음 roomID = device.roomID를 사용하여 각 방에 해당하는 기기를 표시합니다.
self.home.rooms().batched()
.combineLatest(self.home.devices().batched())
.receive(on: DispatchQueue.main)
.catch { error in
// Failed to load rooms and devices
return Just((Set<Room>(), Set<HomeDevice>()))
}
.map { rooms, devices in
var devicesByRoom = [Room: [HomeDevice]]()
for room in rooms where room.structureID == currentStructureID {
devicesByRoom[room] = devices.filter { $0.roomID == room.id }
}
return devicesByRoom
}.assign(to: &self.$devicesByRoom)
샘플 방 호출
방 목록 가져오기
Home 클래스를 사용하면 방 목록을 가져오고 방의 속성에 액세스할 수 있습니다.
let allRoomsChanges = self.home.rooms() let allRooms = try await allRoomsChanges.list() let room = allRooms.first! XCTAssertTrue(allRooms.contains(room)) print("id \(room.id) ") print("name \(room.name) ")
방 만들기
Structure에서 새 방을 만들려면 다음 단계를 따르세요.
let testName = "Test Room Name" var newRoom: Room! do { newRoom = try await structure.createRoom(name: testName) XCTAssertNotNil(newRoom) } catch let _ as HomeError { // Code for handling the exception }
방 삭제하기
또는 방을 삭제할 수도 있습니다.
val roomToDelete = structure.rooms().list().filter { it.name == "room_id1" }.firstOrNull() structure.deleteRoom(roomToDelete!!)
ID를 사용하여 방을 삭제할 수도 있습니다.
let roomToDelete = allRooms.first(where: { $0.id == room.id }) if let roomToDelete1 = roomToDelete { do { try await structure.deleteRoom(roomToDelete1) } catch let _ as HomeError { // Code for handling the exception } }
기기가 있는 방이 삭제되면 기기는 여전히 구조에 있지만 더 이상 방에 할당되지 않습니다.
기기를 다른 방으로 이동하기
Structure를 사용하면 기기를 다른 방으로 이동할 수도 있습니다.
do { try await structure.move(device: light, to: room) } catch let _ as HomeError { // Code for handling the exception }
방 이름 변경하기
setName(_:)
메서드를 호출하여 방 이름을 변경합니다.
let updatedRoom = try await theRoom.setName("new room name")
방 이름을 변경할 때 원래 Room 구조체는 그대로 유지되고 변경사항은 반환된 업데이트된 Room 객체에 반영됩니다.
이름이 유니코드 코드 포인트(문자) 한도인 60을 초과하면 잘리고 오류가 발생하지 않습니다. 개발자는 긴 이름을 처리할 책임이 있으며, 예를 들어 사용자에게 이름이 잘릴 것이라고 알릴지 여부를 결정할 수 있습니다.