API Structure su iOS

È possibile accedere alle API Structure tramite le API Home per iOS.

Per utilizzare le API Structure, importa prima il pacchetto GoogleHomeSDK nella tua app:

import GoogleHomeSDK

Gestione degli errori

Alcuni metodi nelle API Home generano un'eccezione HomeError, pertanto ti consigliamo di utilizzare un blocco do-catch per rilevare HomeError in queste chiamate.

Quando gestisci HomeError, controlla i campi code e message per scoprire cosa è andato storto.

Gli errori non gestiti causeranno l'arresto anomalo dell'app.

Per saperne di più, consulta Gestione degli errori.

API Structure

Home rappresenta il grafico della casa ed è il punto di accesso all'API Structure. Fornisce riferimenti a strutture, stanze e dispositivi.

Structure rappresenta una struttura nel grafico della casa. Fornisce l'accesso ai metadati della struttura, come id e name.

Utilizza structures() per ottenere tutte le strutture nel tuo account. Le strutture vengono restituite sotto forma di Query, che offre una scelta di modi per utilizzare i dati:

API Descrizione
stream() Restituisce un Publisher che emette ogni oggetto singolarmente man mano che vengono apportate modifiche.
batched() Restituisce un Publisher che emette il risultato corrente come Set di oggetti. Ogni Set emesso rappresenta lo stato attuale del grafico degli oggetti.
list() Restituisce il risultato corrente come Set di oggetti.

La chiamata structures().list() potrebbe non restituire immediatamente un insieme valido di strutture. Se la tua app è reattiva e chiama stream() per abbonarsi a tutte le modifiche alla struttura per gestire l'interfaccia utente, alla fine dovrebbe essere restituito un elenco valido di strutture. Esistono altre situazioni in cui potrebbe essere restituito un elenco di strutture vuoto, ad esempio se lo smartphone dell'utente perde la connettività o se l'utente ha revocato le autorizzazioni alla tua app. Assicurati di gestire questi casi nella tua 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)

Chiamate di esempio a Struttura

Ottieni un insieme di strutture

Chiamare list() su Query<Structure> restituisce l'insieme di elementi più recente:

// Get a stream of all structures accessible to the user
let allStructuresChanges = self.home.structures()
let allStructures = try? await allStructuresChanges.list()

Quando progetti un'app reattiva, ti consigliamo di utilizzare le chiamate batched() e stream() anziché list(), perché queste producono automaticamente dati quando il grafico della casa cambia.

Recuperare le proprietà della struttura

Con l'elenco delle strutture a portata di mano, puoi accedere alle relative proprietà:

// 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) ")

Trovare una struttura in base al nome

Se conosci il nome di una struttura, puoi accedervi anche utilizzando la proprietà name:

do {
  structure1 = try await home.structures().list().first(where: { $0.name == "Main House" })
} catch let _ as HomeError {
  // Code for handling the exception
}

Da qui sono accessibili le proprietà, le stanze e i dispositivi di ogni struttura.

Lavorare con più strutture

Per utilizzare più di una struttura, ottieni un riferimento separato per ciascuna:

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
}

Camere

Una stanza contiene un gruppo di dispositivi. Una stanza fa sempre parte di una struttura e una struttura può avere più stanze. Se rimuovi una stanza da una struttura, i dispositivi presenti nella stanza non vengono rimossi dalla struttura. Tuttavia, se la stanza viene eliminata, i dispositivi al suo interno non vengono più assegnati.

Utilizza Home.rooms() per recuperare tutte le stanze dell'account, quindi utilizza roomID = device.roomID per visualizzare i dispositivi corrispondenti in ogni stanza.

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)

Esempio di chiamate a una stanza

Ottenere un elenco di stanze

Utilizzando la classe Home, puoi ottenere un elenco di stanze e accedere alle relative proprietà:

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) ")

Crea una stanza virtuale

Per creare una nuova stanza in 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
}

Eliminare una stanza

In alternativa, puoi eliminare una stanza:

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

Puoi anche eliminare una camera utilizzando il relativo 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
  }
}

Se viene eliminata una stanza con dispositivi, questi rimarranno nella struttura ma non saranno più assegnati a una stanza.

Spostare i dispositivi in un'altra stanza

Structure ti consente anche di spostare un dispositivo in un'altra stanza:

do {
  try await structure.move(device: light, to: room)
} catch let _ as HomeError {
  // Code for handling the exception
}

Modificare il nome di una stanza

Chiama il metodo setName(_:) per modificare il nome di una stanza:

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

Quando si modifica il nome di una stanza, la struttura Room originale rimane invariata e la modifica viene riportata nell'oggetto Room aggiornato restituito.

I nomi verranno troncati se superano il limite di 60 punti di codice Unicode (caratteri) e non verranno generati errori. Gli sviluppatori sono responsabili della gestione dei nomi lunghi e, ad esempio, possono decidere se informare gli utenti che i nomi verranno troncati.