Interfejsy Structure API na iOS

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

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

import GoogleHomeSDK

Obsługa błędów

Niektóre metody w interfejsach API Home wywołują błądHomeError, dlatego zalecamy użycie bloku do-catch, aby przechwycić błądHomeError w tych wywołaniach.

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

Każdy nieobsługiwany błąd spowoduje awarię aplikacji.

Więcej informacji znajdziesz w sekcji Postępowanie z błędami.

Structure API

Home reprezentuje graf Home i jest punktem wejścia do interfejsu Structure API. Zawiera odniesienia do struktur, pomieszczeń i urządzeń.

Structure reprezentuje strukturę w Twoim grafie domowym. Zapewnia dostęp do metadanych struktury, takich jak id i name.

Użyj polecenia structures(), aby uzyskać wszystkie struktury na koncie. Struktury są zwracane w postaci obiektu Query, który umożliwia wybór sposobu wykorzystania danych:

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

Wywołanie funkcji structures().list() może nie zwrócić od razu prawidłowego zbioru struktur. Jeśli Twoja aplikacja jest reaktywna i wywołuje funkcję stream(), aby subskrybować wszystkie zmiany struktury, aby sterować interfejsem, powinna zwracać prawidłową listę struktur. Pusta lista struktury może zostać zwrócona również w innych sytuacjach, np. gdy telefon użytkownika traci łączność lub użytkownik cofnie uprawnienia do aplikacji. W takich przypadkach aplikacja powinna odpowiednio reagować.

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

Pobieranie zestawu struktur

Wywołanie funkcji list() w przypadku obiektu Query<Structure> zwraca najnowszy zbiór 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 użyj wywołań batched()stream(), a nie list(), ponieważ te pierwsze automatycznie generują dane, gdy zmienia się wykres główny.

Pobieranie właściwości struktury

Po uzyskaniu listy 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) ")

Znajdowanie struktury według nazwy

Jeśli znasz nazwę struktury, możesz 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
}

Tutaj możesz przeglądać właściwości, pomieszczenia i urządzenia w poszczególnych strukturach.

Praca z wieloma strukturami

Aby używać więcej niż 1 struktury, pobierz osobne odwołania 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

Pokój zawiera grupę urządzeń. Pokój jest zawsze częścią struktury, a struktura może mieć wiele pokoi. Usunięcie pokoju z struktury nie powoduje usunięcia z niej urządzeń znajdujących się w tym pokoju. Jeśli jednak sala zostanie usunięta, urządzenia w niej zostaną odpięte.

Użyj polecenia Home.rooms(), aby pobrać wszystkie pokoje na koncie, a potem polecenia roomID = device.roomID, aby wyświetlić odpowiednie urządzenia w każdym pokoju.

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)

Przykładowe połączenia z pokoju

Pobieranie listy pokoi

Za pomocą klasy Home możesz uzyskać listę pokoi i uzyskać do nich dostęp:

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

Pokój możesz też usunąć, podając jego identyfikator:

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 pomieszczenie z urządzeniami zostanie usunięte, urządzenia pozostaną w strukturze, ale nie będą już przypisane do pomieszczenia.

Przenoszenie urządzeń do innego pomieszczenia

Structure umożliwia też przenoszenie urządzenia do innego pokoju:

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

Zmienianie nazwy pokoju

Aby zmienić nazwę pokoju, wywołaj metodę setName(_:):

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

Gdy zmienisz nazwę sali, oryginalna struktura Room pozostanie bez zmian, a zmiana zostanie odzwierciedlona w zwróconym zaktualizowanym obiekcie Room.

Lista interfejsów API

Po utworzeniu instancji interfejsu Home są dostępne te interfejsy Structure API:

Interfejs API Opis
devices() wyświetlać wszystkie urządzenia widoczne dla tego konta;
device(id:) Pobierz Publisher dla określonego urządzenia, które emituje bieżący stan i ponownie w przypadku wszelkich przyszłych aktualizacji stanu.
structures() Pobierz wszystkie struktury na koncie Google. Zwraca Query<Structure>, który zawiera dalsze opcje wyszukiwania i filtrowania.
structure(id:) Pobierz strukturę o pasującym identyfikatorze.
rooms() Pobierz wszystkie pokoje na koncie Google. Zwraca Query<strRoom>, który zawiera dalsze opcje wyszukiwania i filtrowania.
room(id:) Uzyskaj Publisher dla określonego pokoju, który emituje bieżący stan i ponownie w przypadku wszelkich przyszłych zmian stanu.

Interfejs Structure ma te interfejsy API:

Interfejs API Opis
deleteRoom(id:) usunąć pokój za pomocą identyfikatora pokoju.
id Unikalny identyfikator systemu struktury.
move(device:, to:) Przenoszenie urządzenia do innego pomieszczenia w strukturze.
move(device:, to:) Przenoszenie urządzenia o danym identyfikatorze do pokoju o danym 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 Podana przez użytkownika nazwa struktury.

Room ma te interfejsy API:

Interfejs API Opis
id Unikalny identyfikator systemu pokoju.
name Podana przez użytkownika nazwa pokoju.
structureID Unikalny identyfikator systemu budynku, do którego należy pokój.