مراقبة حالة الجهاز على أجهزة iOS

في واجهات برمجة التطبيقات Home APIs لنظام التشغيل iOS، يمكن رصد التغييرات في الحالة في المنزل من خلال استخدام إطار عمل Combine في Swift. يمكن رصد التغييرات في الهياكل والغرف والبيانات الوصفية للأجهزة وحالتها في واجهات برمجة التطبيقات Home باستخدام أي واجهة برمجة تطبيقات باستخدام HomeDevice. ويتم ذلك من خلال الاشتراك في الناشرين الذين يعرضون القيم من الأحداث غير المتزامنة.

عند إضافة أي عنصر في مجموعة أو حذفه أو تعديله، يتم عرض أحدث لقطة لمجموعة.

على المطوّر استنتاج التغييرات المحدّدة من خلال مقارنة هذه لقطة الشاشة بنسخة قديمة. يمكن استخدام الحقل id المقدَّم لكل نوع عنصر رئيسي في Home APIs لهذا الغرض.

كيفية إزالة عناصر اختيارية

عندما يكون العنصر اختياريًا، استخدِم if let أو guard لإزالة التغليف بأمان. لا تستخدِم ! لأنّه لا يُسمح باستخدام ! أبدًا ما لم يكن المطوّر يقينًا من أنّ العنصر لا يمكن أن يكون فارغًا.

تم تحديد مَعلمة الإدخال structureID في المثال على أنّها String?، ما يعني أنّها سلسلة اختيارية وبإمكانها أن تكون فارغة. تعثر هذه الدالة على عنصر Structure استنادًا إلى الإدخال في structureID.

في ما يلي الطريقة التي ننصح بها بمعالجة العناصر الاختيارية:

func structure(structureID: String?) -> Structure? {
    guard let structureID else { return nil }
    return structures.first { $0.id == structureID }
  }

كيفية استخدام الناشرين

في ما يلي بعض الأمثلة الأساسية على العمل مع الناشرين في واجهة برمجة التطبيقات Home. في الأمثلة التالية، يجب إنشاء مثيل من Home.

var home: Home?

قبل الوصول إلى المجموعات، احرص على فك تشفيرها لأنّها اختيارية:

guard let home else { return nil }

تتبُّع التغييرات في بنية

تؤدي التغييرات التالية على بنية إلى تنشيط هذه المجموعة:

home.structures().batched()
  .compactMap { $0.first(where: { $0.id = myStructureID} }
  .removeDuplicates()
  .sink { structure in
    if let structure = structure {
      print("Structure \(structure.id) updated to \(structure.name)")
    }
  }

تتبُّع التغييرات على جهاز معيّن

تؤدي التغييرات التالية على أحد الأجهزة إلى تفعيل هذه المجموعة:

home.devices().batched()
  .compactMap { deviceList -> HomeDevice? in
    deviceList.filter { $0.name == "Bedroom Lamp"}.first
  }
  .removeDuplicates()
  .sink { lampDevice in
    if lampDevice != nil {
      print("The bedroom lamp has changed!")
    }
  }

تتبُّع التغييرات في سمة معيّنة على جهاز

استخدِم أي سمة متوافقة مع الجهاز وHome APIs. للحصول على القائمة الكاملة، يُرجى الاطّلاع على Trait.

device.types.subscribe(OnOffLightDeviceType.self)
  .compactMap { $0.matterTraits.onOffTrait }
  .removeDuplicates()
  .sink { onOffState in
    if let onOffState = onOffState {
      print("Got new state update: \(onOffState.onOff)")
    }
  }

تتبُّع التغييرات التي تطرأ على نوع معيّن على جهاز

تؤدي التغييرات التالية على نوع الجهاز إلى تفعيل هذه المجموعة:

استخدِم أي نوع من أجهزة Matter المتوافقة مع واجهات برمجة التطبيقات Home APIs. للاطّلاع على القائمة الكاملة، يُرجى الاطّلاع على DeviceType.

device.types.subscribe(DimmableLightDeviceType.self)
  .compactMap { $0.matterTraits.levelControlTrait }
  .removeDuplicates()
  .sink { dimmableLightDevice in
    if let dimmableLightDevice = dimmableLightDevice
      print("Got new state update! \(levelControlTrait.currentLevel)")
    }
  }

تتبُّع التغييرات في غرفة ضمن بنية

تؤدي التغييرات التالية على غرفة إلى تنشيط هذه المجموعة:

لتتبُّع حالات إضافة الأجهزة أو إزالتها من غرفة، استخدِم devices() query.

home.rooms().batched()
  .sink { rooms in
    print("Got a new updated set of rooms!")
    for room in rooms {
      print("Got room #\(room.name)")
    }
  }

الاشتراك في الأحداث

في واجهات برمجة التطبيقات Home APIs، تُستخدَم الأحداث لرصد التغيُّرات في حالة الجهاز.

self.cancellable = self.device.types.subscribe(FanDeviceType.self)
  .receive(on: DispatchQueue.main)
  .catch { error in
    Logger.error("Error getting FanDeviceType: \(error)")
    return Empty<FanDeviceType, Never>().eraseToAnyPublisher()
  }
  .sink { [weak self] fanDeviceType in
    self?.fanDeviceType = fanDeviceType
    self?.updateTileInfo()
  }
}