Se puede acceder a las APIs de Structure a través de las APIs de Home para iOS.
Para trabajar con las APIs de Structure, primero importa el paquete GoogleHomeSDK en tu app:
import GoogleHomeSDK
Manejo de errores
Algunos métodos de las APIs de Home arrojan un HomeError, por lo que te recomendamos que uses un bloque do-catch para detectar HomeError en esas llamadas.
Cuando manejes HomeError, verifica sus campos code y message para saber qué ocurrió.
Cualquier error no controlado provocará que falle la app.
Para obtener más información, consulta Manejo de errores.
API de Structure
Home representa el gráfico de la casa y es el punto de entrada a la API de Structure.
Proporciona referencias a estructuras, habitaciones y dispositivos.
Structure representa una estructura en tu Home Graph. Proporciona acceso a metadatos de estructura, como id y name.
Usa structures() para obtener todas las estructuras de tu cuenta. Las estructuras se devuelven en forma de un Query, que ofrece varias formas de consumir sus datos:
| API | Descripción |
|---|---|
stream() |
Devuelve un Publisher que emite cada objeto de forma individual a medida que se producen los cambios. |
batched() |
Devuelve un Publisher que emite el resultado actual como un Set de objetos. Cada Set emitido representa el estado actual del gráfico de objetos. |
list() |
Devuelve el resultado actual como un Set de objetos. |
Es posible que la llamada structures().list() no devuelva de inmediato un conjunto válido de estructuras. Si tu app es reactiva y llama a stream() para suscribirse a todos los cambios de estructura que controlan la IU, eventualmente se debería devolver una lista válida de estructuras. Hay otras situaciones en las que se podría devolver una lista de estructura vacía, por ejemplo, si el teléfono del usuario pierde la conectividad o si el usuario revocó los permisos de tu app. Debes asegurarte de controlar estos casos en tu app.
@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)
Llamadas de Sample Structure
Obtén un conjunto de estructuras
Si llamas a list() en un Query<Structure>, se devuelve el conjunto de elementos más reciente:
// Get a stream of all structures accessible to the user let allStructuresChanges = self.home.structures() let allStructures = try? await allStructuresChanges.list()
Cuando diseñes una app reactiva, te convendrá usar llamadas batched() y stream() en lugar de list(), ya que estas producen datos automáticamente cuando cambia el gráfico principal.
Obtén propiedades de la estructura
Con la lista de estructuras en mano, puedes acceder a sus propiedades:
// 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) ")
Cómo encontrar una estructura por su nombre
Si conoces el nombre de una estructura, también puedes acceder a ella con la propiedad name:
do { structure1 = try await home.structures().list().first(where: { $0.name == "Main House" }) } catch let _ as HomeError { // Code for handling the exception }
Desde allí, se puede acceder a las propiedades, las habitaciones y los dispositivos de cada estructura.
Trabaja con varias estructuras
Para usar más de una estructura, obtén una referencia separada para cada una:
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 }
Habitaciones
Una habitación contiene un grupo de dispositivos. Una habitación siempre forma parte de una estructura, y una estructura puede tener varias habitaciones. Si quitas una habitación de una estructura, no se quitarán los dispositivos de esa habitación de la estructura. Sin embargo, si se borra la habitación, los dispositivos que se encuentran en ella dejarán de estar asignados.
Usa Home.rooms() para recuperar todas las habitaciones de la cuenta y, luego, usa roomID = device.roomID para mostrar los dispositivos correspondientes en cada habitación.
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)
Llamadas de Sample Room
Obtén una lista de salas
Con la clase Home, puedes obtener una lista de salas y acceder a sus propiedades:
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) ")
Crear una sala
Sigue estos pasos para crear una sala nueva en un 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 }
Cómo borrar una habitación
También puedes borrar una sala de la siguiente manera:
val roomToDelete = structure.rooms().list().filter { it.name == "room_id1" }.firstOrNull() structure.deleteRoom(roomToDelete!!)
También puedes borrar una sala con su ID:
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 } }
Si se borra una habitación con dispositivos, estos seguirán en la estructura, pero ya no estarán asignados a una habitación.
Cómo mover dispositivos a otra habitación
Structure también te permite mover un dispositivo a otra habitación:
do { try await structure.move(device: light, to: room) } catch let _ as HomeError { // Code for handling the exception }
Cómo cambiar el nombre de una habitación
Llama al método setName(_:) para cambiar el nombre de una habitación:
let updatedRoom = try await theRoom.setName("new room name")
Cuando se cambia el nombre de una habitación, la struct Room original permanece igual y el cambio se refleja en el objeto Room actualizado que se devuelve.
Los nombres se truncarán si superan el límite de 60 puntos de código Unicode (caracteres) y no se mostrará ningún error. Los desarrolladores son responsables de controlar los nombres largos y, por ejemplo, pueden decidir si quieren informar a los usuarios que los nombres se truncarán.
Grupos de dispositivos
Un grupo de dispositivos representa una colección de dispositivos definidos por el usuario dentro de una sola estructura.
Al igual que las habitaciones físicas, los grupos de dispositivos pertenecen a una sola estructura. Sin embargo, a diferencia de las habitaciones, los grupos de dispositivos son agrupaciones lógicas. Un dispositivo puede pertenecer a varios grupos de dispositivos de forma simultánea. Los grupos de dispositivos pueden contener hasta 100 dispositivos.
Los grupos de dispositivos se representan con la entidad Group, que es distinta de HomeDevice.
Obtén una lista de grupos de dispositivos
Para observar todos los grupos de dispositivos en una estructura, haz lo siguiente:
for await groups in structure.deviceGroups.batched() {
for group in groups {
print("Found group: \(group.name) with ID: \(group.id)")
}
}
Crea un grupo de dispositivos
Usa GroupManagementTrait en la estructura para crear un grupo de dispositivos:
let groupsManagementTrait = try await structure.traits(Google.GroupManagementTrait)
let _ = try await groupsManagementTrait.createUserDefinedGroup(withName: "Kitchen Lights",
withDevices: [light1, light2])
Administra la pertenencia a un grupo
Para agregar miembros a un grupo existente, sigue estos pasos:
let groupManagementTrait = try await structure.traits(Google.GroupManagementTrait.self)
groupManagementTrait.addGroupMembers(
groupObjectId: group.id,
memberDeviceObjectIds = [light3.id],
)
Para quitar miembros de un grupo, haz lo siguiente:
let groupManagementTrait = try await structure.traits(Google.GroupManagementTrait.self)
_ = try await groupManagementTrait.removeGroupMembers(
groupObjectId: group.id,
memberDeviceObjectIdsArray: Array(removedIDs)
Cómo cambiar el nombre de un grupo de dispositivos
Para cambiar el nombre de un grupo de dispositivos, actualiza el campo name de GroupTrait:
let groupTrait = group.traits.get(Google.GroupTrait.self)
_ = try await groupTrait.update { $0.name = "Movie Corner" }
Borra un grupo de dispositivos
Para borrar un grupo de dispositivos de una estructura, haz lo siguiente:
let groupManagementTrait = try await structure.traits.get(Google.GroupManagementTrait.self)
_ = try await groupManagementTrait.deleteGroup(groupObjectId: group.id)