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

يمكن الوصول إلى واجهات برمجة التطبيقات الخاصة بالبنية من خلال واجهات برمجة التطبيقات الخاصة بالمنزل على أجهزة iOS.

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

import GoogleHomeSDK

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

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

عند معالجة HomeError، تحقَّق من الحقلَين code وmessage لمعرفة المشكلة.

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

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

واجهة برمجة التطبيقات الخاصة بالبنية

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

تمثّل 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 {
      // Failed to load structures
      return Just([Structure]())
    }
    .assign(to: \.structures, on: self)

نماذج لعمليات طلب البيانات من واجهة برمجة التطبيقات الخاصة بالبنية

الحصول على مجموعة من البِنى

يؤدي طلب list() على Query<Structure> إلى عرض أحدث مجموعة من العناصر:

// Get a stream of all structures accessible to the user
let allStructuresChanges = 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 = 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 _ 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 _ 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
}

الغُرف

تحتوي الغرفة على مجموعة من الأجهزة. تكون الغرفة دائمًا جزءًا من بنية، وقد تحتوي البنية على غرف متعددة. لا تؤدي إزالة غرفة من بنية إلى إزالة الأجهزة الموجودة في تلك الغرفة من البنية. ومع ذلك، إذا تم حذف الغرفة، ستصبح الأجهزة الموجودة فيها غير مخصّصة.

استخدِم Home.rooms() لاسترداد جميع الغرف في الحساب، ثم استخدِم roomID = device.roomID لعرض الأجهزة المقابلة في كل غرفة.

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)

نماذج لعمليات طلب البيانات من واجهة برمجة التطبيقات الخاصة بالغرف

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

باستخدام الفئة 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 _ 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 _ as HomeError {
    // Code for handling the exception
  }
}

إذا تم حذف غرفة تحتوي على أجهزة، ستظل الأجهزة في البنية ولكن لن يتم تخصيصها لغرفة بعد الآن.

نقل الأجهزة إلى غرفة أخرى

تتيح لك Structure أيضًا نقل جهاز إلى غرفة أخرى:

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

تغيير اسم غرفة

استخدِم الطريقة setName(_:) لتغيير اسم غرفة:

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

عند تغيير اسم غرفة، يظل عنصر Room الأصلي كما هو ويظهر التغيير في عنصر Room المعدَّل الذي يتم عرضه.

سيتم اقتطاع الأسماء إذا تجاوزت عدد الأحرف المسموح به في يونيكود (60 حرفًا)، ولن يتم عرض أي أخطاء. يتحمّل المطوّرون مسؤولية معالجة الأسماء الطويلة، ويمكنهم مثلاً تحديد ما إذا كانوا يريدون إبلاغ المستخدمين بأنّه سيتم اقتطاع الأسماء.