Interfejsy Structure API na iOS

Dostęp do interfejsów Structure API można uzyskać za pomocą interfejsów Home API na iOS.

Aby korzystać z interfejsów Structure API, najpierw zaimportuj pakiet GoogleHomeSDK do aplikacji:

import GoogleHomeSDK

Obsługa błędów

Niektóre metody w interfejsach Home API zgłaszają wyjątek HomeError, dlatego zalecamy użycie bloku do-catch, aby przechwycić wyjątek HomeError w przypadku tych wywołań.

Podczas obsługi HomeError sprawdź pola codemessage, aby dowiedzieć się, co poszło nie tak.

Wszelkie nieobsłużone błędy spowodują awarię aplikacji.

Więcej informacji znajdziesz w sekcji Obsługa błędów.

Structure API

Home reprezentuje wykres domu i jest punktem wejścia do interfejsu Structure API. Zawiera odniesienia do domów, pomieszczeń i urządzeń.

Structure reprezentuje strukturę w grafie domu. Umożliwia dostęp do metadanych struktury, takich jak idname.

Użyj structures(), aby pobrać wszystkie struktury na koncie. Struktury są zwracane w postaci obiektu Query, który oferuje różne sposoby wykorzystania danych:

Interfejs API Opis
stream() Zwraca Publisher, który emituje każdy obiekt osobno w miarę wprowadzania zmian.
batched() Zwraca Publisher, który emituje bieżący wynik jako Set obiektów. Każdy wyemitowany element Set reprezentuje bieżący stan wykresu obiektów.
list() Zwraca bieżący wynik jako Set obiektów.

Wywołanie structures().list() może nie od razu zwrócić prawidłowego zestawu struktur. Jeśli aplikacja jest reaktywna i wywołuje funkcję stream(), aby subskrybować wszystkie zmiany struktury w celu sterowania interfejsem, powinna w końcu zwrócić prawidłową listę struktur. Pusta lista struktur może zostać zwrócona w innych sytuacjach, np. gdy telefon użytkownika utraci połączenie lub gdy użytkownik cofnie uprawnienia aplikacji. Pamiętaj, aby obsłużyć te przypadki w swojej aplikacji.

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

Przykładowe wywołania Structure

Pobieranie zestawu struktur

Wywołanie funkcji list() na Query<Structure> zwraca najnowszy zestaw elementów:

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

Podczas projektowania aplikacji reaktywnej warto używać wywołań batched()stream() zamiast list(), ponieważ automatycznie generują one dane, gdy zmienia się wykres domu.

Pobieranie właściwości struktury

Gdy masz już listę struktur, możesz uzyskać dostęp do ich właściwości:

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

Znajdź strukturę według nazwy

Jeśli znasz nazwę struktury, możesz też uzyskać do niej dostęp za pomocą właściwości name:

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

Stamtąd można uzyskać dostęp do usług, pomieszczeń i urządzeń w każdym domu.

Praca z wieloma strukturami

Aby użyć więcej niż jednej struktury, uzyskaj osobne odwołanie do każdej z nich:

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
}

Pokoje

Pomieszczenie zawiera grupę urządzeń. Pokój jest zawsze częścią struktury, a struktura może mieć wiele pokoi. Usunięcie pomieszczenia ze struktury nie spowoduje usunięcia urządzeń z tego pomieszczenia. Jeśli jednak pomieszczenie zostanie usunięte, urządzenia w nim staną się nieprzypisane.

Użyj Home.rooms(), aby pobrać wszystkie pomieszczenia na koncie, a następnie użyj roomID = device.roomID, aby wyświetlić odpowiednie urządzenia w każdym pomieszczeniu.

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)

Połączenia z pokoju prób

Pobieranie listy pokoi

Za pomocą klasy Home możesz pobrać listę pokoi i uzyskać dostęp do ich właściwości:

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

Utwórz pokój

Aby utworzyć nowe pomieszczenie w 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
}

Usuwanie pomieszczenia

Możesz też usunąć pokój:

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

Możesz też usunąć pokój za pomocą jego identyfikatora:

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

Jeśli usuniesz pomieszczenie z urządzeniami, urządzenia nadal będą w strukturze, ale nie będą już przypisane do pomieszczenia.

Przenoszenie urządzeń do innego pomieszczenia

Structure umożliwia też przeniesienie urządzenia do innego pomieszczenia:

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

Zmienianie nazwy pomieszczenia

Wywołaj metodę setName(_:) , aby zmienić nazwę pokoju:

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

Podczas zmiany nazwy pokoju oryginalna struktura Room pozostaje bez zmian, a zmiana jest odzwierciedlana w zwracanym zaktualizowanym obiekcie Room.

Nazwy zostaną obcięte, jeśli przekroczą limit 60 punktów kodowych Unicode (znaków), i nie zostaną zgłoszone żadne błędy. Deweloperzy odpowiadają za obsługę długich nazw i mogą na przykład zdecydować, czy chcą informować użytkowników o tym, że nazwy będą skracane.

Lista interfejsów API

Po utworzeniu instancji Home można uzyskać dostęp do tych interfejsów API struktury:

Interfejs API Opis
devices() Pobierz wszystkie urządzenia widoczne na tym koncie.
device(id:) Uzyskaj Publisher dla określonego urządzenia, które emituje bieżący stan, a także w przypadku przyszłych aktualizacji stanu.
structures() Pobierz wszystkie struktury na koncie Google. Zwraca obiekt Query<Structure>, który udostępnia dodatkowe opcje pobierania i filtrowania.
structure(id:) Pobierz strukturę o pasującym identyfikatorze.
rooms() Pobierz wszystkie pokoje na koncie Google. Zwraca obiekt Query<strRoom>, który udostępnia dodatkowe opcje pobierania i filtrowania.
room(id:) Otrzymuj Publisher dla określonego pomieszczenia, które emituje bieżący stan, a także w przypadku przyszłych aktualizacji stanu.

Structure ma te interfejsy API:

Interfejs API Opis
deleteRoom(id:) Usuń pokój za pomocą identyfikatora pokoju.
id Unikalny identyfikator struktury w systemie.
move(device:, to:) Przenieś urządzenie do innego pomieszczenia w strukturze.
move(device:, to:) Przenieś urządzenie o podanym identyfikatorze do pokoju o podanym identyfikatorze.
move(devices:, to:) Przenosi podane urządzenia do podanego pomieszczenia.
move(devices:, to:) Przenosi urządzenia o podanych identyfikatorach do pokoju o podanym identyfikatorze.
name Nazwa struktury podana przez użytkownika.

Room ma te interfejsy API:

Interfejs API Opis
id Unikalny identyfikator systemowy pokoju.
name Nazwa pokoju podana przez użytkownika.
structureID Unikalny identyfikator systemowy struktury, do której należy pokój.