Structure API는 iOS용 Home API를 통해 액세스할 수 있습니다.
Structure API를 사용하려면 먼저 GoogleHomeSDK
패키지를 앱으로 가져옵니다.
import GoogleHomeSDK
오류 처리
Home API의 일부 메서드는 HomeError
을 발생시키므로 이러한 호출에서 do-catch
블록을 사용하여 HomeError
을 포착하는 것이 좋습니다.
HomeError
를 처리할 때는 code
및 message
필드를 확인하여 문제가 무엇인지 알아봅니다.
처리되지 않은 오류가 있으면 앱이 비정상 종료됩니다.
자세한 내용은 오류 처리를 참고하세요.
Structure API
Home
는 홈 그래프를 나타내며 Structure API의 진입점입니다.
구조, 방, 기기에 대한 참조를 제공합니다.
Structure
: Home 그래프의 구조를 나타냅니다. id
및 name
와 같은 구조 메타데이터에 대한 액세스를 제공합니다.
structures()
를 사용하여 계정의 모든 구조를 가져옵니다. 구조는 데이터를 소비하는 방법을 선택할 수 있는 Query
형식으로 반환됩니다.
API | 설명 |
---|---|
stream() |
변경사항이 발생할 때 각 객체를 개별적으로 내보내는 Publisher 를 반환합니다. |
batched() |
현재 결과를 객체의 Set 로 내보내는 Publisher 를 반환합니다. 내보내는 각 Set 는 객체 그래프의 현재 상태를 나타냅니다. |
list() |
현재 결과를 객체의 Set 로 반환합니다. |
structures().list()
호출이 유효한 구조 집합을 즉시 반환하지 않을 수 있습니다. 앱이 반응형이고 stream()
를 호출하여 모든 구조 변경사항을 구독하여 UI를 구동하는 경우 유효한 구조 목록이 결국 반환됩니다. 빈 구조체 목록이 반환될 수 있는 다른 상황도 있습니다. 예를 들어 사용자의 휴대전화 연결이 끊어지거나 사용자가 앱의 권한을 취소한 경우입니다. 이러한 사례는 앱에서 처리해야 합니다.
@Published public private(set) var structures: [Structure] = []
private var structuresCancellable: AnyCancellable?
self.structuresCancellable = home
.structures()
.batched()
.receive(on: DispatchQueue.main)
.map { Array($0) }
.catch {
Logger.error("Failed to load structures: \($0)")
return Just([Structure]())
}
.assign(to: \.structures, on: self)
샘플 구조 호출
구조 집합 가져오기
Query<Structure>
에서 list()
를 호출하면 가장 최근 요소 집합이 반환됩니다.
// Get a stream of all structures accessible to the user let allStructuresChanges = try await 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 = try await 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 error 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 error as HomeError { // Code for handling the exception } do { structure2 = try await home.structures().list().first(where: { $0.name == "Guest Cottage" }) } catch let error 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
Logger.error("Failed to load rooms and devices: \(error)")
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)
샘플 Room 호출
회의실 목록 가져오기
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 error 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 error as HomeError { // Code for handling the exception } }
기기가 있는 방이 삭제되면 기기는 여전히 구조물에 있지만 더 이상 방에 할당되지 않습니다.
기기를 다른 방으로 이동하기
Structure
를 사용하면 기기를 다른 방으로 이동할 수도 있습니다.
do { try await structure.move(device: light, to: room) } catch let error as HomeError { // Code for handling the exception }
API 목록
Home
인스턴스가 생성되면 이를 통해 다음 Structure API에 액세스할 수 있습니다.
API | 설명 |
---|---|
devices() |
이 계정에 표시되는 모든 기기를 가져옵니다. |
device(id:) |
현재 상태를 내보내고 향후 상태 업데이트 시 다시 내보내는 지정된 기기의 Publisher 를 가져옵니다. |
structures() |
Google 계정의 모든 구조를 가져옵니다. 추가 검색 및 필터링 옵션을 제공하는 Query<Structure> 를 반환합니다. |
structure(id:) |
일치하는 ID가 있는 구조를 가져옵니다. |
rooms() |
Google 계정의 모든 객실을 가져옵니다. 추가 검색 및 필터링 옵션을 제공하는 Query<strRoom> 를 반환합니다. |
room(id:) |
현재 상태를 내보내고 향후 상태 업데이트 시 다시 내보내는 지정된 방의 Publisher 를 가져옵니다. |
Structure
에는 다음과 같은 API가 있습니다.
API | 설명 |
---|---|
deleteRoom(id:) |
객실 ID로 객실을 삭제합니다. |
id |
구조물의 고유 시스템 ID입니다. |
move(device:, to:) |
구조물 내 다른 방으로 기기를 이동합니다. |
move(device:, to:) |
지정된 ID의 기기를 지정된 ID의 방으로 이동합니다. |
move(devices:, to:) |
지정된 기기를 지정된 방으로 이동합니다. |
move(devices:, to:) |
지정된 ID가 있는 기기를 지정된 ID가 있는 공간으로 이동합니다. |
name |
사용자가 제공한 구조의 이름입니다. |
Room
에는 다음 API가 있습니다.
API | 설명 |
---|---|
id |
객실의 고유 시스템 ID입니다. |
name |
사용자가 제공한 방 이름입니다. |
structureID |
객실이 속한 구조물의 고유 시스템 ID입니다. |