คุณเข้าถึง Structure API ได้ผ่าน Home API สำหรับ iOS
หากต้องการใช้ Structure API ให้นำเข้าแพ็กเกจ GoogleHomeSDK ไปยังแอปก่อน โดยทำดังนี้
import GoogleHomeSDK
การจัดการข้อผิดพลาด
เมธอดบางอย่างใน Home API จะแสดงHomeError ดังนั้นเราขอแนะนำให้คุณใช้บล็อก do-catch เพื่อตรวจหาHomeError ในการเรียกเหล่านั้น
เมื่อจัดการ HomeError ให้ตรวจสอบฟิลด์ code และ message
เพื่อดูว่าเกิดข้อผิดพลาดใด
ข้อผิดพลาดที่ไม่ได้จัดการจะส่งผลให้แอปขัดข้อง
ดูข้อมูลเพิ่มเติมได้ที่ การจัดการข้อผิดพลาด
Structure API
Home แสดงกราฟบ้านและเป็นจุดแรกเข้าของ Structure API
โดยจะมีการอ้างอิงถึงโครงสร้าง ห้อง และอุปกรณ์
Structure แสดงโครงสร้างในกราฟบ้าน โดยจะให้สิทธิ์เข้าถึง
ข้อมูลเมตาของโครงสร้าง เช่น 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)
ตัวอย่างการเรียกใช้โครงสร้าง
รับชุดโครงสร้าง
การเรียกใช้ list() ใน Query<Structure> จะแสดงผล Set of
elements ล่าสุด
// Get a stream of all structures accessible to the user let allStructuresChanges = 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 = 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 }
จากนั้น คุณจะเข้าถึงพร็อพเพอร์ตี้ ห้อง และอุปกรณ์ของแต่ละโครงสร้างได้
ทำงานกับโครงสร้างหลายรายการ
หากต้องการใช้โครงสร้างมากกว่า 1 รายการ ให้รับการอ้างอิงแยกต่างหากสำหรับแต่ละโครงสร้าง
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 }
ห้องพัก
ห้องประกอบด้วยกลุ่มอุปกรณ์ ห้องแชทจะเป็นส่วนหนึ่งของโครงสร้างเสมอ และโครงสร้างหนึ่งๆ อาจมีห้องแชทหลายห้อง การนำห้องออกจากโครงสร้างจะไม่ นำอุปกรณ์ในห้องนั้นออกจากโครงสร้าง อย่างไรก็ตาม หากมีการลบห้อง อุปกรณ์ในห้องนั้นจะกลายเป็นอุปกรณ์ที่ไม่ได้มอบหมาย
ใช้ 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)
การโทรในห้องตัวอย่าง
รับรายการห้อง
เมื่อใช้คลาส 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!!)
นอกจากนี้ คุณยังลบห้องพักโดยใช้รหัสของห้องพักได้ด้วย โดยทำดังนี้
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 struct เดิมจะยังคงเหมือนเดิม และ
การเปลี่ยนแปลงจะแสดงในออบเจ็กต์ Room ที่อัปเดตแล้วซึ่งส่งคืน
ระบบจะตัดชื่อหากเกินขีดจำกัด 60 Code Point ของ Unicode (อักขระ) และจะไม่มีข้อผิดพลาด นักพัฒนาแอปมีหน้าที่จัดการชื่อที่ยาว และสามารถตัดสินใจได้ว่าจะแจ้งให้ผู้ใช้ทราบว่าระบบจะตัดชื่อให้สั้นลงหรือไม่