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