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 swojej aplikacji:
import GoogleHomeSDK
Obsługa błędów
Niektóre metody w interfejsach Home API zgłaszają błąd
HomeError, dlatego zalecamy używanie bloku do-catch, aby przechwytywać błędy
HomeError w tych wywołaniach.
Podczas obsługi błędu HomeError sprawdź pola code i message
, 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.
Interfejs Structure API
Home reprezentuje wykres Home i jest punktem wejścia do interfejsu Structure API.
Zawiera odniesienia do struktur, pomieszczeń i urządzeń.
Structure reprezentuje strukturę na wykresie Home. Umożliwia dostęp do metadanych struktury, takich jak id i name.
Aby uzyskać wszystkie struktury na koncie, użyj structures() to. Struktury są zwracane w postaci
Query, która 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 emitowany Set reprezentuje bieżący stan wykresu obiektów. |
list() |
Zwraca bieżący wynik jako Set obiektów. |
Wywołanie structures().list() może nie zwrócić od razu prawidłowego zestawu struktur. Jeśli Twoja aplikacja jest reaktywna i wywołuje stream(), aby subskrybować wszystkie zmiany struktury w celu sterowania interfejsem, w końcu powinna zostać zwrócona prawidłowa lista struktur. Istnieją też inne sytuacje, w których może zostać zwrócona pusta lista struktur, np. gdy telefon użytkownika utraci połączenie lub gdy użytkownik cofnie uprawnienia Twojej aplikacji. Musisz zadbać o obsługę tych przypadków 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 {
// Failed to load structures
return Just([Structure]())
}
.assign(to: \.structures, on: self)
Przykładowe wywołania struktury
Pobieranie zestawu struktur
Wywołanie list() w przypadku Query<Structure> zwraca najnowszy zestaw elementów:
// Get a stream of all structures accessible to the user let allStructuresChanges = self.home.structures() let allStructures = try? await allStructuresChanges.list()
Podczas projektowania aplikacji reaktywnej warto używać wywołań batched() i stream() zamiast list(), ponieważ automatycznie generują one dane, gdy zmienia się wykres Home.
Pobieranie właściwości struktury
Mając 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 = 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 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 _ as HomeError { // Code for handling the exception }
Stamtąd można uzyskać dostęp do właściwości, pomieszczeń i urządzeń każdej struktury.
Praca z wieloma strukturami
Aby używać więcej niż 1 struktury, uzyskaj osobne odniesienie 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 _ 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 }
Pokoje
Pokój zawiera grupę urządzeń. Pokój jest zawsze częścią struktury, a struktura może mieć wiele pomieszczeń. Usunięcie pokoju ze struktury nie powoduje usunięcia urządzeń w tym pokoju ze struktury. Jeśli jednak pokój zostanie usunięty, urządzenia w tym pokoju zostaną odłączone.
Aby
pobrać wszystkie pokoje na koncie, użyj Home.rooms(), a następnie użyj 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
// 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)
Przykładowe wywołania pokoju
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) ")
Tworzenie pokoju
Aby utworzyć nowy pokój w 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 }
Usuwanie pokoju
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 _ as HomeError { // Code for handling the exception } }
Jeśli usuniesz pokój z urządzeniami, urządzenia nadal będą w strukturze, ale nie będą już przypisane do pokoju.
Przenoszenie urządzeń do innego pokoju
Structure umożliwia też przenoszenie urządzeń do innego pokoju:
do { try await structure.move(device: light, to: room) } catch let _ as HomeError { // Code for handling the exception }
Zmienianie nazwy pokoju
Aby zmienić nazwę pokoju, wywołaj
setName(_:)
metodę:
let updatedRoom = try await theRoom.setName("new room name")
Podczas zmiany nazwy pokoju oryginalna struktura Room pozostaje taka sama, a zmiana jest odzwierciedlana w zwracanym zaktualizowanym obiekcie Room.
Nazwy dłuższe niż 60 punktów kodowych Unicode (znaków) zostaną obcięte i nie zostaną zgłoszone żadne błędy. Deweloperzy są odpowiedzialni za obsługę długich nazw i mogą na przykład zdecydować, czy chcą informować użytkowników o tym, że nazwy zostaną obcięte.