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żywanie bloku do-catch do przechwytywania wyjątku HomeError w przypadku tych wywołań.
Podczas obsługi 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.
Structure API
Home reprezentuje wykres domu i jest punktem wejścia do interfejsu Structure API.
Zawiera odniesienia do struktur, pomieszczeń i urządzeń.
Structure reprezentuje strukturę na wykresie domu. Zapewnia dostęp do metadanych struktury, takich jak id i name.
Użyj structures(), aby pobrać wszystkie struktury na koncie. Struktury są zwracane w formie Query, która oferuje różne sposoby wykorzystania danych:
| Interfejs API | Opis |
|---|---|
stream() |
Zwraca obiekt 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 znak Set reprezentuje bieżący stan grafu 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 Twoja 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 być zwracana w innych sytuacjach, np. gdy telefon użytkownika utraci łączność lub gdy użytkownik cofnie uprawnienia aplikacji. Pamiętaj, aby obsługiwać te przypadki w 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)
Wywołania Sample Structure
Pobieranie zestawu struktur
Wywołanie funkcji list() na urządzeniu 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 główny.
Pobieranie właściwości struktury
Mając listę domów, 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) ")
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 _ 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 _ 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
Pomieszczenie zawiera grupę urządzeń. Pomieszczenie zawsze jest częścią struktury, a struktura może zawierać wiele pomieszczeń. Usunięcie pomieszczenia ze struktury nie spowoduje usunięcia urządzeń znajdujących się w tym pomieszczeniu ze struktury. 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
// 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)
Wywołania Sample Room
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ć nowy pokój na koncie 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 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 _ 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 _ as HomeError { // Code for handling the exception }
Zmiana nazwy pomieszczenia
Wywołaj metodę
setName(_:)
aby zmienić nazwę pokoju:
let updatedRoom = try await theRoom.setName("new room name")
Gdy zmienisz nazwę pokoju, oryginalna struktura Room pozostanie bez zmian, a zmiana zostanie odzwierciedlona w zwróconym 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 zostaną skrócone.
Grupy urządzeń
Grupa urządzeń to zdefiniowany przez użytkownika zbiór urządzeń w ramach jednej struktury.
Podobnie jak pomieszczenia fizyczne, grupy urządzeń należą do jednej struktury. W przeciwieństwie do pomieszczeń grupy urządzeń są jednak grupami logicznymi. Urządzenie może należeć do kilku grup urządzeń jednocześnie. Grupy urządzeń mogą zawierać maksymalnie 100 urządzeń.
Grupy urządzeń są reprezentowane przez element Group, który różni się od elementu HomeDevice.
Pobieranie listy grup urządzeń
Aby zobaczyć wszystkie grupy urządzeń w strukturze:
for await groups in structure.deviceGroups.batched() {
for group in groups {
print("Found group: \(group.name) with ID: \(group.id)")
}
}
Tworzenie grupy urządzeń
Aby utworzyć grupę urządzeń, kliknij GroupManagementTrait w strukturze:
let groupsManagementTrait = try await structure.traits(Google.GroupManagementTrait)
let _ = try await groupsManagementTrait.createUserDefinedGroup(withName: "Kitchen Lights",
withDevices: [light1, light2])
Zarządzanie członkostwem w grupach
Aby dodać członków do istniejącej grupy:
let groupManagementTrait = try await structure.traits(Google.GroupManagementTrait.self)
groupManagementTrait.addGroupMembers(
groupObjectId: group.id,
memberDeviceObjectIds = [light3.id],
)
Aby usunąć użytkowników z grupy:
let groupManagementTrait = try await structure.traits(Google.GroupManagementTrait.self)
_ = try await groupManagementTrait.removeGroupMembers(
groupObjectId: group.id,
memberDeviceObjectIdsArray: Array(removedIDs)
Zmiana nazwy grupy urządzeń
Aby zmienić nazwę grupy urządzeń, zaktualizuj pole GroupTraitname:
let groupTrait = group.traits.get(Google.GroupTrait.self)
_ = try await groupTrait.update { $0.name = "Movie Corner" }
Usuwanie grupy urządzeń
Aby usunąć grupę urządzeń ze struktury:
let groupManagementTrait = try await structure.traits.get(Google.GroupManagementTrait.self)
_ = try await groupManagementTrait.deleteGroup(groupObjectId: group.id)