Trong Home API cho iOS, bạn có thể theo dõi các thay đổi về trạng thái trong nhà thông qua việc sử dụng khung Combine trong Swift. Bạn có thể theo dõi các thay đổi về cấu trúc, phòng, siêu dữ liệu thiết bị và trạng thái thiết bị trong Home API bằng bất kỳ API nào sử dụng HomeDevice
. Việc này được thực hiện bằng cách đăng ký với nhà xuất bản hiển thị các giá trị từ các sự kiện không đồng bộ.
Khi bất kỳ mục nào trong một bộ sưu tập được thêm, xoá hoặc sửa đổi, ảnh chụp nhanh mới nhất của bộ sưu tập sẽ được trả về.
Nhà phát triển có trách nhiệm suy luận các thay đổi cụ thể bằng cách so sánh ảnh chụp nhanh này với một bản sao cũ hơn. Bạn có thể sử dụng trường id
được cung cấp cho mỗi loại đối tượng mẹ trong Home API cho mục đích này.
Cách mở gói các đối tượng không bắt buộc
Khi một đối tượng là không bắt buộc, hãy dùng if let
hoặc guard
để giải gói đối tượng một cách an toàn. Đừng dùng !
vì bạn không bao giờ nên dùng !
trừ phi nhà phát triển chắc chắn rằng đối tượng không thể là nil.
Tham số đầu vào structureID
trong ví dụ được xác định là String?
, tức là một chuỗi không bắt buộc và có thể có giá trị rỗng. Hàm này tìm thấy đối tượng Structure
dựa trên dữ liệu đầu vào trong structureID
.
Sau đây là cách bạn nên xử lý các đối tượng không bắt buộc:
func structure(structureID: String?) -> Structure? {
guard let structureID else { return nil }
return structures.first { $0.id == structureID }
}
Cách sử dụng nhà xuất bản
Sau đây là một số ví dụ cơ bản về cách làm việc với các nhà xuất bản trong Home API. Đối với các ví dụ sau, bạn phải tạo một phiên bản của Home
.
var home: Home?
Trước khi truy cập vào các tập hợp, hãy nhớ mở gói chúng vì đây là các tập hợp không bắt buộc:
guard let home else { return nil }
Theo dõi các thay đổi đối với cấu trúc
Những thay đổi sau đây đối với một cấu trúc sẽ kích hoạt bộ sưu tập này:
- Tên cấu trúc
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)")
}
}
Theo dõi các thay đổi đối với một thiết bị cụ thể
Những thay đổi sau đây đối với một thiết bị sẽ kích hoạt bộ sưu tập này:
- Trạng thái kết nối
- Tên thiết bị
- Gói hội viên phòng
- Tập hợp các trait được hỗ trợ
- Tập hợp các loại được hỗ trợ
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!")
}
}
Theo dõi các thay đổi đối với một đặc điểm cụ thể trên thiết bị
Sử dụng mọi đặc điểm mà thiết bị và Home API hỗ trợ. Để xem danh sách đầy đủ, hãy xem 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)")
}
}
Theo dõi các thay đổi đối với một loại cụ thể trên thiết bị
Những thay đổi sau đây đối với một loại thiết bị sẽ kích hoạt bộ sưu tập này:
- Thay đổi đối với mọi đặc điểm trong loại thiết bị được tạo
Sử dụng mọi loại thiết bị Matter mà Home API hỗ trợ. Để xem danh sách đầy đủ, hãy xem 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)")
}
}
Theo dõi các thay đổi đối với một phòng trong ngôi nhà
Những thay đổi sau đây đối với một phòng sẽ kích hoạt bộ sưu tập này:
Để theo dõi thời điểm thiết bị được thêm hoặc xoá khỏi một phòng, hãy sử dụng devices()
truy vấn.
home.rooms().batched()
.sink { rooms in
print("Got a new updated set of rooms!")
for room in rooms {
print("Got room #\(room.name)")
}
}
Đăng ký nhận thông báo về sự kiện
Trong Home API, các sự kiện được dùng để phát hiện những thay đổi về trạng thái của thiết bị.
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()
}
}