מעקב אחרי מצב המכשיר ב-iOS

בממשקי ה-API של Home ל-iOS, אפשר לעקוב אחרי שינויים במצב בבית באמצעות מסגרת Combine ב-Swift. אפשר לעקוב אחרי שינויים במבנים, בחדרים, במטא-נתונים של המכשיר ובמצב המכשיר ב-Home APIs באמצעות כל ממשק API באמצעות HomeDevice. כדי לעשות זאת, צריך להירשם לבעלי תוכן דיגיטלי שחשפו ערכים מאירועים אסינכרונים.

כשמוסיפים, מוחקים או משנים פריט כלשהו באוסף, המערכת מחזירה את קובץ snapshot העדכני ביותר של האוסף.

המפתח צריך להסיק את השינויים הספציפיים על ידי השוואה של קובץ ה-snapshot הזה לעותק ישן יותר. אפשר להשתמש לשם כך בשדה id שסופק לכל סוג של אובייקט הורה בממשקי Home API.

איך לפתוח אובייקטים אופציונליים

כשאובייקט הוא אופציונלי, משתמשים ב-if let או ב-guard כדי לפתוח את האריזה של האובייקט בצורה בטוחה. אין להשתמש ב-! כי אסור להשתמש ב-! אלא אם המפתח יודע בוודאות שהאובייקט לא יכול להיות nil.

פרמטר הקלט structureID בדוגמה מוגדר בתור String?, כלומר זוהי מחרוזת אופציונלית שיכולה להיות גם null. הפונקציה הזו מאתרת את האובייקט Structure על סמך הקלט ב-structureID.

כך מומלץ לטפל באובייקטים אופציונליים:

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

איך משתמשים באתרי חדשות

בהמשך מפורטות כמה דוגמאות בסיסיות לעבודה עם בעלי תוכן דיגיטלי ב-Home API. בדוגמאות הבאות צריך ליצור מופע של 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!")
    }
  }

מעקב אחר שינויים במאפיין ספציפי במכשיר

אפשר להשתמש בכל מאפיין שנתמך במכשיר ובממשקי ה-API של Home. הרשימה המלאה מופיעה במאמר 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().

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()
  }
}