您可以透過 iOS 適用的 Home API 存取 Structure API。
如要使用 Structure API,請先將 GoogleHomeSDK
套件匯入應用程式:
import GoogleHomeSDK
處理錯誤
Home API 中的某些方法會擲回 HomeError
,因此建議您使用 do-catch
區塊,在這些呼叫中擷取 HomeError
。
處理 HomeError
時,請檢查其 code
和 message
欄位,瞭解錯誤所在。
任何未處理的錯誤都會導致應用程式當機。
詳情請參閱「錯誤處理」一文。
Structure API
Home
代表 Home 圖表,也是 Structure API 的進入點。提供結構體、房間和裝置的參照。
Structure
代表 Home 圖表中的結構。可存取 id
和 name
等結構中繼資料。
使用 structures()
取得帳戶中的所有結構體。系統會以 Query
的形式傳回結構,提供多種使用資料的方式:
API | 說明 |
---|---|
stream() |
傳回 Publisher ,可在發生變更時個別發出每個物件。 |
batched() |
傳回 Publisher ,該物件會將目前結果以物件的 Set 形式發出。每個產生的 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()
設計回應式應用程式時,建議您使用 batched()
和 stream()
呼叫,而非 list()
,因為這些呼叫會在主圖表變更時自動產生資料。
取得結構體屬性
有了結構體清單,您就可以存取結構體的屬性:
// 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 }
變更房間名稱
呼叫 setName(_:)
方法,變更房間名稱:
let updatedRoom = try await theRoom.setName("new room name")
變更房間名稱時,原始 Room
結構體會維持不變,而變更會反映在傳回的更新版 Room
物件中。
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 的裝置移至 ID 為指定 ID 的房間。 |
move(devices:, to:) |
將指定裝置移至指定房間。 |
move(devices:, to:) |
將具有指定 ID 的裝置移至具有指定 ID 的房間。 |
name |
使用者提供的結構體名稱。 |
Room
提供下列 API:
API | 說明 |
---|---|
id |
房間的專屬系統 ID。 |
name |
使用者提供的聊天室名稱。 |
structureID |
房間所屬結構體的專屬系統 ID。 |