В API Home для iOS отслеживать изменения состояния в доме можно с помощью фреймворка Combine в Swift. Отслеживать изменения в структурах, комнатах, метаданных устройств и состоянии устройств в API Home можно с помощью любого API, используя HomeDevice. Для этого нужно подписаться на издателей, которые предоставляют значения из асинхронных событий.
Когда в подборку добавляется, удаляется или изменяется какой-либо объект, возвращается последний снимок подборки.
Разработчик может определить, какие именно изменения произошли, сравнив этот снимок с более ранней копией. Для этого можно использовать поле id, которое есть у каждого родительского объекта в Home API.
Как развернуть необязательные объекты
Если объект необязательный, используйте 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 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 Google 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, поддерживаемый API Home. Полный список приведен в разделе 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)")
}
}
Как оформить подписку на события
В API Home события используются для обнаружения изменений в состоянии устройства.
self.cancellable = self.device.types.subscribe(FanDeviceType.self)
.receive(on: DispatchQueue.main)
.catch { error in
// Error getting FanDeviceType
return Empty<FanDeviceType, Never>().eraseToAnyPublisher()
}
.sink { [weak self] fanDeviceType in
self?.fanDeviceType = fanDeviceType
self?.updateTileInfo()
}
}