คุณเข้าถึง 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 {
// Failed to load structures
return Just([Structure]())
}
.assign(to: \.structures, on: self)
ตัวอย่างการเรียกโครงสร้าง
รับชุดโครงสร้าง
การเรียก list() ใน Query<Structure> จะแสดงผลชุดองค์ประกอบล่าสุดของ
// 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
// 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!!)
นอกจากนี้ คุณยังลบห้องโดยใช้รหัสของห้องได้ด้วย
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 ที่อัปเดตซึ่งแสดงผล
ระบบจะตัดชื่อให้สั้นลงหากยาวเกินขีดจำกัด Code Point ของ Unicode (อักขระ) 60 ตัว และจะไม่มีการแสดงข้อผิดพลาด นักพัฒนาแอปมีหน้าที่รับผิดชอบในการจัดการชื่อที่ยาว และสามารถตัดสินใจได้ว่าจะแจ้งให้ผู้ใช้ทราบว่าระบบจะตัดชื่อให้สั้นลงหรือไม่