ממשקי Structure API ב-iOS

אפשר לגשת אל Structure APIs דרך Home APIs ל-iOS.

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

import GoogleHomeSDK

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

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

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

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

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

Structure API

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

Structure מייצג מבנה בתרשים Home. הוא מספק גישה למטא-נתונים של המבנה, כמו 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)

דוגמה לשיחות עם מבנה

קבלת קבוצה של מבנים

הפונקציה Calling list() on a 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 property:

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)

דוגמאות לשיחות בחדרים

קבלת רשימת חדרים

באמצעות המחלקה 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 המעודכן שמוחזר.

שמות שיכילו יותר מ-60 תווים יחתכו, ולא יוצגו שגיאות. המפתחים אחראים לטיפול בשמות ארוכים. לדוגמה, הם יכולים להחליט אם הם רוצים להודיע למשתמשים שהשמות יקוצרו.

רשימת ממשקי API

אחרי שיוצרים מופע של Home, אפשר לגשת דרכו לממשקי ה-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 המזהה הייחודי של המבנה שאליו החדר שייך.