ממשקי Structure API ב-iOS

אפשר לגשת לממשקי Structure API דרך ממשקי Home API ל-iOS.

כדי לעבוד עם ממשקי Structure API, קודם צריך לייבא את החבילה GoogleHomeSDK לאפליקציה:

import GoogleHomeSDK

טיפול בשגיאות

שיטות מסוימות ב-Home APIs גורמות להשלכת HomeError, לכן מומלץ להשתמש בבלוק do-catch כדי לתפוס את HomeError בקריאות האלה.

כשמטפלים ב-HomeError, צריך לבדוק את השדות code ו-message כדי להבין מה השתבש.

שגיאות שלא מטופלות יגרמו לקריסה של האפליקציה.

מידע נוסף זמין במאמר טיפול בשגיאות.

Structure API

Home מייצג את הגרף 'דף הבית', והוא נקודת הכניסה ל-Structure API. הוא מספק הפניות למבנים, לחדרים ולמכשירים.

Structure מייצג מבנה בתרשים הבית. הוא מספק גישה למטא-נתונים של מבנה, כמו id ו-name.

אפשר להשתמש ב-structures() כדי לקבל את כל המבנים בחשבון. המבנים מוחזרים בצורת Query, שמציע כמה דרכים לצרוך את הנתונים שלו:

API תיאור
stream() הפונקציה מחזירה Publisher שמפיק כל אובייקט בנפרד כשמתרחשים שינויים.
batched() הפונקציה מחזירה Publisher שמפיק את התוצאה הנוכחית כ-Set של אובייקטים. כל אירוע Set שנפלט מייצג את המצב הנוכחי של תרשים האובייקטים.
list() הפונקציה מחזירה את התוצאה הנוכחית כ-Set של אובייקטים.

יכול להיות שהקריאה ל-structures().list() לא תחזיר מיד קבוצה תקינה של מבנים. אם האפליקציה שלכם היא תגובהית ומפעילה את stream() כדי להירשם לכל השינויים במבנה כדי להפעיל את ממשק המשתמש, בסופו של דבר אמורה להוחזר רשימה תקינה של מבנים. יש מצבים אחרים שבהם יכולה להוחזר רשימת מבנים ריקה, למשל אם הטלפון של המשתמש מאבד את החיבור או אם המשתמש ביטל את ההרשאות לאפליקציה. חשוב לטפל במקרים האלה באפליקציה.

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

קריאות לדוגמה למבנה

אחזור קבוצה של מבנים

קריאה ל-list() ב-Query<Structure> מחזירה את הקבוצה האחרונה של הרכיבים:

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

כשאתם מתכננים אפליקציה תגובה, מומלץ להשתמש בקריאות batched() ו-stream() במקום בקריאה list(), כי הן יוצרות נתונים באופן אוטומטי כשהתרשים הראשי משתנה.

אחזור מאפייני המבנה

אחרי שתקבלו את רשימת המבנים, תוכלו לגשת למאפיינים שלהם:

// 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 = try await structureChanges.first!

// Get structure properties
print("id \(structure.id) ")
print("name \(structure.name) ")

חיפוש מבנה לפי שם

אם אתם יודעים מה שם המבנה, תוכלו לגשת אליו גם באמצעות המאפיין name:

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

משם אפשר לגשת לנכסים, לחדרים ולמכשירים של כל מבנה.

עבודה עם כמה מבנים

כדי להשתמש ביותר ממבנה אחד, צריך לקבל הפניה נפרדת לכל מבנה:

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

חדרים

חדר מכיל קבוצה של מכשירים. חדר תמיד שייך למבנה, ויכולים להיות במבנה כמה חדרים. הסרת חדר מהמבנה לא מסירה את המכשירים שנמצאים בחדר מהמבנה. עם זאת, אם תמחקו את החדר, המכשירים שבו לא ישויכו יותר.

משתמשים ב-Home.rooms() כדי לאחזר את כל החדרים בחשבון, ואז משתמשים ב-roomID = device.roomID כדי להציג את המכשירים התואמים בכל חדר.

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)

שיחות לדוגמה ב-Room

הצגת רשימת החדרים

באמצעות הכיתה Home אפשר לקבל רשימה של חדרים ולגשת למאפיינים שלהם:

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

יצירת חדר

כדי ליצור חדר חדש ב-Structure:

let testName = "Test Room Name"
var newRoom: Room!
do {
  newRoom = try await structure.createRoom(name: testName)
  XCTAssertNotNil(newRoom)
} catch let error as HomeError {
  // Code for handling the exception
}

מחיקת חדר

לחלופין, אפשר למחוק את החדר:

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

אפשר גם למחוק חדר באמצעות המזהה שלו:

let roomToDelete = allRooms.first(where: { $0.id == room.id })
if let roomToDelete1 = roomToDelete {
  do {
    try await structure.deleteRoom(roomToDelete1)
  } catch let error as HomeError {
    // Code for handling the exception
  }
}

אם תמחקו חדר עם מכשירים, המכשירים עדיין יישארו במבנה, אבל לא ישויכו יותר לחדר.

העברת מכשירים לחדר אחר

Structure מאפשר גם להעביר מכשיר לחדר אחר:

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

שינוי השם של חדר

כדי לשנות את השם של חדר, צריך להפעיל את השיטה setName(_:):

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

כשמשנים את שם החדר, המבנה המקורי של Room נשאר ללא שינוי והשינוי משתקף באובייקט Room המעודכן שמוחזרים.

רשימת ממשקי ה-API

אחרי שיוצרים מופע של Home, אפשר לגשת דרכו לממשקי ה-Structure API הבאים:

API תיאור
devices() הצגת כל המכשירים שגלויים לחשבון הזה.
device(id:) אחזור Publisher למכשיר מסוים שמפיק את המצב הנוכחי, ושוב בכל עדכון עתידי של המצב.
structures() הצגת כל המבנים בחשבון Google. הפונקציה מחזירה Query<Structure> שמספק אפשרויות אחזור וסינון נוספות.
structure(id:) מקבלים את המבנה עם המזהה התואם.
rooms() הצגת כל החדרים בחשבון Google. הפונקציה מחזירה Query<strRoom> שמספק אפשרויות אחזור וסינון נוספות.
room(id:) קבלת Publisher עבור חדר מסוים שמפיק את המצב הנוכחי, ושוב בכל עדכון עתידי של המצב.

ל-Structure יש את ממשקי ה-API הבאים:

API תיאור
deleteRoom(id:) למחוק את החדר באמצעות מזהה החדר.
id מזהה המערכת הייחודי של המבנה.
move(device:, to:) להעביר מכשיר לחדר אחר במבנה.
move(device:, to:) העברת המכשיר עם המזהה הנתון לחדר עם המזהה הנתון.
move(devices:, to:) העברת המכשירים הנתונים לחדר הנתון.
move(devices:, to:) העברת המכשירים עם המזהים שצוינו לחדר עם המזהה שצוין.
name השם של המבנה שסיפק המשתמש.

ל-Room יש את ממשקי ה-API הבאים:

API תיאור
id המזהה הייחודי של החדר במערכת.
name השם של החדר שסיפק המשתמש.
structureID המזהה הייחודי במערכת של המבנה שאליו שייכת החדר.