APIs de Structure en iOS

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 a 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é salió mal.

Cualquier error no controlado provocará que falle tu app.

Para obtener más información, consulta Manejo de errores.

API de Structure

Home representa el grafo 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 el grafo de tu casa. Proporciona acceso a metadatos de estructura, como id y name.

Usa structures() para obtener todas las estructuras de tu cuenta. Las estructuras se muestran en forma de 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 grafo 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 para controlar la IU, se debería devolver una lista válida de estructuras. Hay otras situaciones en las que se podría devolver una lista de estructuras 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 Structure de muestra

Obtén un conjunto de estructuras

Llamar a list() en un Query<Structure> devuelve el conjunto de elementos más reciente de elementos:

// 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 recomendamos que uses las llamadas batched() y stream() en lugar de list(), ya que estas producen datos automáticamente cuando cambia el grafo de la casa.

Obtén propiedades de la estructura

Con la lista de estructuras en la 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) ")

Busca una estructura por 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 independiente a cada estructura:

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. Quitar una habitación de una estructura no quita los dispositivos de esa habitación de la estructura. Sin embargo, si se borra la habitación, los dispositivos de esa habitación dejan 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 Room de muestra

Obtén una lista de habitaciones

Con la clase Home, puedes obtener una lista de habitaciones 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

Para crear una habitación nueva en una Structure, haz lo siguiente:

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

O bien, puedes borrar una habitación de la siguiente manera:

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

También puedes borrar una habitación 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 permanecerán en la estructura, pero ya no estarán asignados a una habitación.

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

Cambia el nombre de una habitación

Llama al setName(_:) método para cambiar el nombre de una habitación:

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

Cuando cambias el nombre de una habitación, la estructura Room original permanece igual y el cambio se refleja en el objeto Room actualizado que se muestra.

Los nombres se truncarán si superan el límite de 60 puntos de código Unicode (caracteres) y no se arrojarán errores. Los desarrolladores son responsables de manejar nombres largos y, por ejemplo, pueden decidir si quieren informar a los usuarios que los nombres se truncarán.