В API Home для iOS отслеживание изменений состояния дома осуществляется с помощью фреймворка Combine в Swift. Отслеживание изменений в структурах, комнатах, метаданных устройства и состоянии устройства в API Home может быть выполнено с помощью любого API, использующего HomeDevice . Это достигается путем подписки на издателей, предоставляющих значения из асинхронных событий.
При добавлении, удалении или изменении любого элемента в коллекции возвращается последний снимок коллекции.
Разработчику предстоит определить конкретные изменения, сравнив этот снимок с более старой копией. Для этой цели можно использовать поле id , предоставляемое для каждого типа родительского объекта в API Home .
Как развернуть необязательные объекты
Если объект является необязательным, используйте if let или guard для безопасного извлечения объекта. Не используйте ! , потому что ! никогда не следует использовать, если разработчик точно не знает, что объект не может быть `nil`.
The input parameter structureID in the example is defined as String? , which means it's a string that is optional and has the possibility of being nil. This function finds the Structure object based on the input in structureID .
Вот как мы рекомендуем обрабатывать необязательные объекты:
func structure(structureID: String?) -> Structure? {
guard let structureID else { return nil }
return structures.first { $0.id == structureID }
}
Как использовать издателей
Ниже приведены несколько базовых примеров работы с издателями в API 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!")
}
}
Отслеживание изменений определенного параметра на устройстве
Используйте любые характеристики, поддерживаемые устройством и 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 , поддерживаемый 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()
}
}