Structure APIs unter iOS

Auf Struktur-APIs kann über die Home APIs für iOS zugegriffen werden.

Wenn Sie mit den Struktur-APIs arbeiten möchten, importieren Sie zuerst das Paket GoogleHomeSDK in Ihre App:

import GoogleHomeSDK

Fehlerbehandlung

Einige Methoden in den Home APIs geben einen HomeError aus. Wir empfehlen daher, einen do-catch Block zu verwenden, um HomeError bei diesen Aufrufen abzufangen.

Prüfen Sie bei der Behandlung von HomeError die Felder code und message , um herauszufinden, was schiefgelaufen ist.

Nicht behandelte Fehler führen zum Absturz Ihrer App.

Weitere Informationen finden Sie unter Fehlerbehandlung.

Struktur-API

Home stellt das Home-Diagramm dar und ist der Einstiegspunkt für die Struktur-API. Sie enthält Verweise auf Strukturen, Räume und Geräte.

Structure stellt eine Struktur in Ihrem Home-Diagramm dar. Sie bietet Zugriff auf Strukturmetadaten wie id und name.

Verwenden Sie structures(), um alle Strukturen in Ihrem Konto abzurufen. Die Strukturen werden in Form einer Query zurückgegeben, die verschiedene Möglichkeiten zur Nutzung der Daten bietet:

API Beschreibung
stream() Gibt einen Publisher zurück, der jedes Objekt einzeln ausgibt, wenn Änderungen vorgenommen werden.
batched() Gibt einen Publisher zurück, der das aktuelle Ergebnis als Set von Objekten ausgibt. Jedes ausgegebene Set stellt den aktuellen Zustand des Objektgraphen dar.
list() Gibt das aktuelle Ergebnis als Set von Objekten zurück.

Der Aufruf structures().list() gibt möglicherweise nicht sofort eine gültige Menge von Strukturen zurück. Wenn Ihre App reaktiv ist und stream() aufruft, um alle Strukturänderungen zu abonnieren, um die Benutzeroberfläche zu steuern, sollte schließlich eine gültige Liste von Strukturen zurückgegeben werden. Es gibt auch andere Situationen, in denen eine leere Strukturliste zurückgegeben werden kann, z. B. wenn die Verbindung des Smartphones des Nutzers unterbrochen wird oder wenn der Nutzer die Berechtigungen für Ihre App widerrufen hat. Sie sollten diese Fälle in Ihrer App behandeln.

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

Beispielaufrufe für Strukturen

Eine Menge von Strukturen abrufen

Wenn Sie list() für eine Query<Structure> aufrufen, wird die letzte Menge von Elementen zurückgegeben:

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

Beim Entwerfen einer reaktiven App sollten Sie batched()- und stream()-Aufrufe anstelle von list() verwenden, da diese automatisch Daten erzeugen, wenn sich das Home-Diagramm ändert.

Strukturattribute abrufen

Mit der Liste der Strukturen können Sie auf die Attribute zugreifen:

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

Struktur anhand des Namens finden

Wenn Sie den Namen einer Struktur kennen, können Sie auch über das Attribut name darauf zugreifen:

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

Von dort aus sind die Attribute, Räume und Geräte für jede Struktur zugänglich.

Mit mehreren Strukturen arbeiten

Wenn Sie mehr als eine Struktur verwenden möchten, rufen Sie für jede Struktur einen separaten Verweis ab:

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
}

Räume

Ein Raum enthält eine Gruppe von Geräten. Ein Raum ist immer Teil einer Struktur und eine Struktur kann mehrere Räume haben. Wenn Sie einen Raum aus einer Struktur entfernen, werden die Geräte in diesem Raum nicht aus der Struktur entfernt. Wenn der Raum jedoch gelöscht wird, werden die Geräte in diesem Raum nicht zugewiesen.

Verwenden Sie Home.rooms(), um alle Räume im Konto abzurufen, und dann roomID = device.roomID, um die entsprechenden Geräte in jedem Raum anzuzeigen.

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)

Beispielaufrufe für Räume

Liste der Räume abrufen

Mit der Klasse Home können Sie eine Liste der Räume abrufen und auf die Attribute zugreifen:

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

Raum erstellen

So erstellen Sie einen neuen Raum in einer 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
}

Raum löschen

Alternativ können Sie einen Raum löschen:

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

Sie können einen Raum auch anhand seiner ID löschen:

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

Wenn ein Raum mit Geräten gelöscht wird, befinden sich die Geräte weiterhin in der Struktur, sind aber keinem Raum mehr zugewiesen.

Geräte in einen anderen Raum verschieben

Mit Structure können Sie ein Gerät auch in einen anderen Raum verschieben:

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

Namen eines Raums ändern

Rufen Sie die setName(_:) Methode auf, um den Namen eines Raums zu ändern:

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

Wenn Sie den Namen eines Raums ändern, bleibt die ursprüngliche Room-Struktur unverändert und die Änderung wird im zurückgegebenen aktualisierten Room-Objekt widergespiegelt.

Namen werden abgeschnitten, wenn sie das Limit von 60 Unicode-Codepunkten (Zeichen) überschreiten. Es werden keine Fehler ausgegeben. Entwickler sind für die Behandlung langer Namen verantwortlich und können beispielsweise entscheiden, ob sie Nutzer darüber informieren möchten, dass Namen abgeschnitten werden.