iOS'te cihaz durumunu izleme

iOS için Home API'lerinde, evdeki durum değişikliklerini gözlemlemek için Swift'te Combine framework kullanılır. Home API'lerindeki yapılarda, odalarda, cihaz meta verilerinde ve cihaz durumunda yapılan değişiklikleri HomeDevice kullanarak herhangi bir API ile gözlemleyebilirsiniz. Bu işlem, eşzamansız etkinliklerden değerler sunan yayıncılara abone olunarak yapılır.

Bir koleksiyondaki herhangi bir öğe eklendiğinde, silindiğinde veya değiştirildiğinde koleksiyonun en son anlık görüntüsü döndürülür.

Bu anlık görüntüyü eski bir kopyayla karşılaştırarak belirli değişiklikleri anlamak geliştiricinin sorumluluğundadır. Bu amaçla, Home API'lerindeki her üst nesne türü için sağlanan id alanı kullanılabilir.

İsteğe bağlı nesneleri sarmalama

Bir nesne isteğe bağlı olduğunda, nesnenin güvenli bir şekilde sarmalanmasını açmak için if let veya guard kullanın. ! öğesini kullanmayın. !, geliştirici nesnenin kesinlikle boş olamayacağını bilmediği sürece hiçbir zaman kullanılmamalıdır.

Örnekteki giriş parametresi structureID, String? olarak tanımlanır. Bu, parametrenin isteğe bağlı bir dize olduğu ve boş olma olasılığı bulunduğu anlamına gelir. Bu işlev, structureID içindeki girişe göre Structure nesnesini bulur.

İsteğe bağlı nesneleri aşağıdaki şekilde kullanmanızı öneririz:

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

Yayıncıları kullanma

Aşağıda, Home API'lerinde yayıncılarla çalışmaya dair bazı temel örnekler verilmiştir. Aşağıdaki örnekler için Home örneği oluşturulmalıdır.

var home: Home?

Koleksiyonlara erişmeden önce, isteğe bağlı oldukları için koleksiyonları açtığınızdan emin olun:

guard let home else { return nil }

Bir yapıda yapılan değişiklikleri izleme

Bir yapıda aşağıdaki değişiklikler yapıldığında bu koleksiyon tetiklenir:

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

Belirli bir cihazdaki değişiklikleri izleme

Bir cihazda aşağıdaki değişiklikler yapıldığında bu koleksiyon tetiklenir:

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!")
    }
  }

Cihazdaki belirli bir özelliğin değişikliklerini izleme

Cihaz ve Home API'leri tarafından desteklenen tüm özellikleri kullanın. Tam liste için Trait konusuna bakın.

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

Cihazdaki belirli bir türde yapılan değişiklikleri izleme

Bir cihaz türünde yapılan aşağıdaki değişiklikler bu koleksiyonu tetikler:

Home API'leri tarafından desteklenen herhangi bir Matter cihaz türünü kullanın. Tam liste için DeviceType sayfasına bakın.

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

Bir yapıdaki odada yapılan değişiklikleri izleme

Bir odada aşağıdaki değişiklikler yapıldığında bu koleksiyon tetiklenir:

Cihazların odaya eklenme veya odadan kaldırılma zamanını izlemek için devices() sorgusunu kullanın.

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

Etkinliklere abone olma

Ev API'lerinde, bir cihazın durumundaki değişiklikleri algılamak için etkinlikler kullanılır.

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