Trong API Nhà thông minh dành 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 API Nhà thông minh bằng bất kỳ API nào sử dụng
HomeDevice. Bạn có thể thực hiện việc này bằng cách đăng ký nhà xuất bản hiển thị các giá trị từ sự kiện không đồng bộ.
Khi bạn thêm, xoá hoặc sửa đổi bất kỳ mục nào trong một tập hợp, hệ thống sẽ trả về ảnh chụp nhanh mới nhất của tập hợp đó.
Nhà phát triển có trách nhiệm suy ra 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
từng loại đối tượng mẹ trong API Nhà thông minh
cho mục đích này.
Cách mở gói đối tượng không bắt buộc
Khi một đối tượng là không bắt buộc, hãy sử dụng if let hoặc guard để mở gói đối tượng một cách an toàn. Đừng sử dụng ! vì ! không bao giờ được sử dụng trừ phi nhà phát triển biết 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à đây là một chuỗi không bắt buộc và có thể là nil. Hàm này tìm đố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 nhà xuất bản trong API Nhà thông minh. Đối với các ví dụ sau đây, bạn phải tạo một thực thể 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 các tập hợp đó vì chúng là không bắt buộc:
guard let home else { return nil }
Theo dõi các thay đổi đối với một cấu trúc
Các thay đổi sau đây đối với một cấu trúc sẽ kích hoạt tập hợp này:
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ể
Các thay đổi sau đây đối với một thiết bị sẽ kích hoạt tập hợp này:
- Trạng thái kết nối
- Tên thiết bị
- Tư cách thành viên trong phòng
- Tập hợp các trait được hỗ trợ
- Tập hợp các loại được hỗ trợ types
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 trait cụ thể trên một thiết bị
Sử dụng mọi trait được thiết bị và API Nhà thông minh 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 một thiết bị
Các thay đổi sau đây đối với một loại thiết bị sẽ kích hoạt tập hợp này:
Sử dụng mọi loại thiết bị Matter được API Nhà thông minh 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 một cấu trúc
Các thay đổi sau đây đối với một phòng sẽ kích hoạt tập hợp này:
- Tên phòng
- Tư cách thành viên trong cấu trúc
Để theo dõi thời điểm thiết bị được thêm vào 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ý sự kiện
Trong API Nhà thông minh, các sự kiện được dùng để phát hiện các thay đổi về trạng thái của một thiết bị.
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()
}
}