As APIs de estrutura podem ser acessadas pelas APIs Home para iOS.
Para trabalhar com as APIs Structure, primeiro importe o pacote GoogleHomeSDK para
seu app:
import GoogleHomeSDK
Tratamento de erros
Alguns métodos nas APIs Home geram um
HomeError. Por isso, recomendamos que você use um bloco do-catch para capturar
HomeError nessas chamadas.
Ao processar HomeError, verifique os campos code e message para saber o que deu errado.
Qualquer erro não tratado vai causar falha no app.
Para mais informações, consulte Tratamento de erros.
API Structure
Home representa o gráfico da casa e é o ponto de entrada da API Structure.
Ele fornece referências a estruturas, salas e dispositivos.
Structure representa uma estrutura no seu gráfico da casa. Ele dá acesso a metadados de estrutura, como id e name.
Use structures() para
receber todas as estruturas na sua conta. As estruturas são retornadas na forma de um
Query, que oferece várias
maneiras de consumir os dados:
| API | Descrição |
|---|---|
stream() |
Retorna um Publisher que emite cada objeto individualmente à medida que as mudanças ocorrem. |
batched() |
Retorna um Publisher que emite o resultado atual como um Set de objetos. Cada Set emitido representa o estado atual do gráfico de objetos. |
list() |
Retorna o resultado atual como um Set de objetos. |
A chamada structures().list() pode não retornar imediatamente um conjunto válido de estruturas. Se o app for reativo e chamar stream() para se inscrever em
todas as mudanças de estrutura para acionar a interface, uma lista válida de estruturas será
retornada eventualmente. Há outras situações em que uma lista de estruturas vazia pode ser retornada, por exemplo, se o smartphone do usuário perder a conectividade ou se ele revogar as permissões do app. Não se esqueça de processar esses casos no 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 {
Logger.error("Failed to load structures: \($0)")
return Just([Structure]())
}
.assign(to: \.structures, on: self)
Exemplos de chamadas de estrutura
Receber um conjunto de estruturas
Chamar list() em um Query<Structure> retorna o conjunto mais recente de elementos:
// Get a stream of all structures accessible to the user let allStructuresChanges = self.home.structures() let allStructures = try? await allStructuresChanges.list()
Ao projetar um app reativo, use chamadas batched() e stream() em vez de list(), porque elas produzem dados automaticamente quando o gráfico inicial muda.
Receber propriedades de estrutura
Com a lista de estruturas em mãos, você pode acessar as propriedades delas:
// 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) ")
Encontrar uma estrutura pelo nome
Se você souber o nome de uma estrutura, também poderá acessá-la usando a propriedade name:
do { structure1 = try await home.structures().list().first(where: { $0.name == "Main House" }) } catch let _ as HomeError { // Code for handling the exception }
A partir daí, é possível acessar propriedades, cômodos e dispositivos de cada estrutura.
Trabalhar com várias estruturas
Para usar mais de uma estrutura, receba uma referência separada para cada uma delas:
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 }
Salas
Um ambiente contém um grupo de dispositivos. Uma sala sempre faz parte de uma estrutura, e uma estrutura pode ter várias salas. Remover um ambiente de uma estrutura não remove os dispositivos desse ambiente da estrutura. No entanto, se o ambiente for excluído, os dispositivos nele vão ficar sem atribuição.
Use Home.rooms() para
recuperar todos os ambientes na conta e roomID = device.roomID para
mostrar os dispositivos correspondentes em cada ambiente.
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)
Exemplos de chamadas da Room
Receber uma lista de salas
Usando a classe Home, é possível receber uma lista de salas e acessar as propriedades delas:
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) ")
Criar uma sala
Para criar um novo ambiente em um 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 }
Excluir um ambiente
Ou, se preferir, exclua uma sala:
val roomToDelete = structure.rooms().list().filter { it.name == "room_id1" }.firstOrNull() structure.deleteRoom(roomToDelete!!)
Também é possível excluir uma sala usando o ID dela:
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 } }
Se um ambiente com dispositivos for excluído, os dispositivos ainda estarão na estrutura, mas não atribuídos a um ambiente.
Mover dispositivos para outro ambiente
Com o Structure, também é possível mover um dispositivo para outro ambiente:
do { try await structure.move(device: light, to: room) } catch let _ as HomeError { // Code for handling the exception }
Mudar o nome de um ambiente
Chame o método
setName(_:)
para mudar o nome de um ambiente:
let updatedRoom = try await theRoom.setName("new room name")
Ao mudar o nome de uma sala, a struct Room original permanece a mesma, e a mudança é refletida no objeto Room atualizado retornado.
Os nomes serão truncados se excederem o limite de 60 pontos de código Unicode (caracteres), e nenhum erro será gerado. Os desenvolvedores são responsáveis por processar nomes longos e, por exemplo, podem decidir se querem informar aos usuários que os nomes serão truncados.