API cấu trúc trên iOS

Bạn có thể truy cập vào Structure API thông qua Home API cho iOS.

Để sử dụng Structure API, trước tiên, hãy nhập gói GoogleHomeSDK vào ứng dụng:

import GoogleHomeSDK

Xử lý lỗi

Một số phương thức trong Home API gửi HomeError, vì vậy, bạn nên sử dụng khối do-catch để nắm bắt HomeError trên những lệnh gọi đó.

Khi xử lý HomeError, hãy kiểm tra các trường codemessage để tìm hiểu điều gì đã xảy ra.

Mọi lỗi không được xử lý sẽ khiến ứng dụng của bạn gặp sự cố.

Để biết thêm thông tin, hãy xem Xử lý lỗi.

Structure API

Home đại diện cho biểu đồ Home và là điểm truy cập vào Structure API. API này cung cấp các tham chiếu đến cấu trúc, phòng và thiết bị.

Structure đại diện cho một cấu trúc trong biểu đồ Home. API này cung cấp quyền truy cập vào siêu dữ liệu cấu trúc, chẳng hạn như idname.

Sử dụng structures() để lấy tất cả cấu trúc trong tài khoản của bạn. Các cấu trúc được trả về dưới dạng Query, cung cấp nhiều cách để sử dụng dữ liệu của cấu trúc:

API Mô tả
stream() Trả về Publisher phát từng đối tượng riêng lẻ khi có thay đổi.
batched() Trả về Publisher phát kết quả hiện tại dưới dạng Set đối tượng. Mỗi Set được phát đại diện cho trạng thái hiện tại của biểu đồ đối tượng.
list() Trả về kết quả hiện tại dưới dạng Set đối tượng.

Lệnh gọi structures().list() có thể không trả về ngay một tập hợp cấu trúc hợp lệ. Nếu ứng dụng của bạn có tính phản ứng và gọi stream() để đăng ký tất cả các thay đổi về cấu trúc nhằm điều khiển giao diện người dùng, thì cuối cùng, một danh sách cấu trúc hợp lệ sẽ được trả về. Có những trường hợp khác mà danh sách cấu trúc trống có thể được trả về, chẳng hạn như nếu điện thoại của người dùng bị mất kết nối hoặc nếu người dùng đã thu hồi quyền đối với ứng dụng của bạn. Bạn nên đảm bảo xử lý những trường hợp này trong ứng dụng.

@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)

Lệnh gọi cấu trúc mẫu

Lấy một tập hợp cấu trúc

Việc gọi list() trên Query<Structure> sẽ trả về Tập hợp phần tử gần đây nhất của:

// Get a stream of all structures accessible to the user
let allStructuresChanges = self.home.structures()
let allStructures = try? await allStructuresChanges.list()

Khi thiết kế một ứng dụng có tính phản ứng, bạn nên sử dụng các lệnh gọi batched()stream() thay vì list(), vì các lệnh gọi này sẽ tự động tạo dữ liệu khi biểu đồ nhà thay đổi.

Lấy các thuộc tính cấu trúc

Khi có danh sách cấu trúc, bạn có thể truy cập vào các thuộc tính của cấu trúc đó:

// 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) ")

Tìm cấu trúc theo tên

Nếu biết tên của một cấu trúc, bạn cũng có thể truy cập vào cấu trúc đó bằng thuộc tính name:

do {
  structure1 = try await home.structures().list().first(where: { $0.name == "Main House" })
} catch let _ as HomeError {
  // Code for handling the exception
}

Từ đó, bạn có thể truy cập vào các thuộc tính, phòng và thiết bị cho từng cấu trúc.

Làm việc với nhiều cấu trúc

Để sử dụng nhiều cấu trúc, hãy lấy một tham chiếu riêng cho từng cấu trúc:

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

Một phòng chứa một nhóm thiết bị. Một phòng luôn là một phần của cấu trúc và một cấu trúc có thể có nhiều phòng. Việc xoá một phòng khỏi cấu trúc không xoá các thiết bị trong phòng đó khỏi cấu trúc. Tuy nhiên, nếu phòng bị xoá, các thiết bị trong phòng đó sẽ trở thành thiết bị chưa được chỉ định.

Sử dụng Home.rooms() để truy xuất tất cả các phòng trong tài khoản, sau đó sử dụng roomID = device.roomID để hiển thị các thiết bị tương ứng trong mỗi phòng.

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)

Lệnh gọi phòng mẫu

Lấy danh sách phòng

Sử dụng lớp Home, bạn có thể lấy danh sách phòng và truy cập vào các thuộc tính của phòng đó:

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) ")

Tạo một phòng

Cách tạo một phòng mới trong 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
}

Xoá phòng

Hoặc bạn có thể xoá một phòng:

val roomToDelete = structure.rooms().list().filter { it.name == "room_id1" }.firstOrNull()
    structure.deleteRoom(roomToDelete!!)

Bạn cũng có thể xoá một phòng bằng mã nhận dạng của phòng đó:

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
  }
}

Nếu một phòng có thiết bị bị xoá, các thiết bị đó vẫn sẽ nằm trong cấu trúc nhưng không còn được chỉ định cho phòng nào nữa.

Di chuyển thiết bị sang một phòng khác

Structure cũng cho phép bạn di chuyển một thiết bị sang một phòng khác:

do {
  try await structure.move(device: light, to: room)
} catch let _ as HomeError {
  // Code for handling the exception
}

Thay đổi tên của một phòng

Gọi phương thức setName(_:) để thay đổi tên của một phòng:

let updatedRoom = try await theRoom.setName("new room name")

Khi bạn thay đổi tên của một phòng, cấu trúc Room ban đầu vẫn giữ nguyên và thay đổi sẽ được phản ánh trong đối tượng Room đã cập nhật được trả về.

Tên sẽ bị cắt ngắn nếu vượt quá giới hạn 60 điểm mã Unicode (ký tự) và sẽ không có lỗi nào được gửi. Nhà phát triển chịu trách nhiệm xử lý tên dài và có thể quyết định xem có muốn thông báo cho người dùng rằng tên sẽ bị cắt ngắn hay không.