واجهات برمجة تطبيقات Structure على نظام التشغيل iOS

يمكن الوصول إلى واجهات Structure APIs من خلال واجهات Home APIs لنظام التشغيل iOS.

لاستخدام واجهات برمجة التطبيقات Structure، عليك أولاً استيراد حزمة GoogleHomeSDK إلى تطبيقك:

import GoogleHomeSDK

معالجة الأخطاء

تُطلق بعض الطرق في واجهات برمجة تطبيقات Home الرمز HomeError، لذا ننصحك باستخدام كتلة do-catch لاكتشاف الرمز HomeError في هذه الطلبات.

عند التعامل مع HomeError، تحقَّق من الحقلَين code وmessage لمعرفة الخطأ الذي حدث.

سيؤدي حدوث أي أخطاء لم تتم معالجتها إلى تعطُّل تطبيقك.

لمزيد من المعلومات، يُرجى الاطّلاع على التعامل مع الأخطاء.

Structure API

يمثّل Home الرسم البياني للمنزل، وهو نقطة الدخول إلى Structure API. ويوفّر مراجع للمباني والغرف والأجهزة.

يمثّل Structure بنية في الرسم البياني لمنزلك. تتيح الوصول إلى بيانات وصفية خاصة بالبنية، مثل id وname.

استخدِم structures() للحصول على جميع البُنى في حسابك. يتم عرض البِنى على شكل Query، ما يتيح لك اختيار طرق استهلاك البيانات:

واجهة برمجة التطبيقات الوصف
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)

أمثلة على مكالمات الغرف

الحصول على قائمة بالغرف

باستخدام فئة 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 نقطة رمز يونيكود (حرفًا)، ولن يتم عرض أي أخطاء. يتحمّل المطوّرون مسؤولية التعامل مع الأسماء الطويلة، ويمكنهم مثلاً تحديد ما إذا كانوا يريدون إعلام المستخدمين بأنّه سيتم اقتطاع الأسماء.

قائمة واجهات برمجة التطبيقات

بعد إنشاء مثيل من Home، يمكن الوصول إلى واجهات برمجة التطبيقات التالية الخاصة بالبنية من خلاله:

واجهة برمجة التطبيقات الوصف
devices() الحصول على جميع الأجهزة المرئية لهذا الحساب
device(id:) احصل على Publisher لجهاز محدّد يعرض الحالة الحالية، ثم يعرضها مرة أخرى عند إجراء أي تحديثات مستقبلية للحالة.
structures() الحصول على جميع المباني في حساب Google تعرض هذه الدالة Query<Structure> يوفّر خيارات إضافية للاسترداد والفلترة.
structure(id:) الحصول على البنية التي تتضمّن رقم التعريف المطابق
rooms() الحصول على جميع الغرف في حساب Google تعرض هذه الدالة Query<strRoom> يوفّر خيارات إضافية للاسترداد والفلترة.
room(id:) احصل على Publisher لغرفة محدّدة تعرض الحالة الحالية، ثم مرة أخرى عند إجراء أي تحديثات مستقبلية على الحالة.

يتضمّن Structure واجهات برمجة التطبيقات التالية:

واجهة برمجة التطبيقات الوصف
deleteRoom(id:) حذف غرفة باستخدام رقم تعريف الغرفة
id المعرّف الفريد للنظام الخاص بالبنية.
move(device:, to:) نقل جهاز إلى غرفة أخرى في المبنى
move(device:, to:) نقل الجهاز الذي يحمل رقم التعريف المحدّد إلى الغرفة التي تحمل رقم التعريف المحدّد
move(devices:, to:) تنقل هذه الطريقة الأجهزة المحدّدة إلى الغرفة المحدّدة.
move(devices:, to:) تنقل هذه الطريقة الأجهزة التي تحمل أرقام التعريف المحدّدة إلى الغرفة التي تحمل رقم التعريف المحدّد.
name اسم البنية الذي يقدّمه المستخدم.

يتضمّن Room واجهات برمجة التطبيقات التالية:

واجهة برمجة التطبيقات الوصف
id المعرّف الفريد للنظام الخاص بالغرفة.
name اسم الغرفة الذي يحدّده المستخدم
structureID المعرّف الفريد للنظام الخاص بالبنية التي تنتمي إليها الغرفة