我正在尝试实施 CLMonitor 来监控我的 iBeacons。
@MainActor class BeaconHandler: ObservableObject {
static let shared = BeaconHandler()
private let locationManager: CLLocationManager
private var monitor: CLMonitor?
private init() {
self.locationManager = CLLocationManager()
Task(priority: .high) {
self.monitor = await CLMonitor("BeaconHandler")
}
}
func addToMonitor(identifier: String, major: Int, minor: Int) {
Task {
let beaconCondition = CLMonitor.BeaconIdentityCondition(uuid: UUID(uuidString: identifier)!, major: UInt16(major), minor: UInt16(minor))
await self.monitor?.add(beaconCondition, identifier: identifier, assuming: .unsatisfied)
}
}
func removeFromMonitor(identifier: String) {
Task {
await self.monitor?.remove(identifier)
}
}
func getEventStateFor(identifier: String) async -> CLMonitor.Event.State {
if self.monitor == nil {
return .unmonitored
}
if let monitoredRecord = await self.monitor!.record(for: identifier) {
return monitoredRecord.lastEvent.state
}
return .unmonitored
}
}
我想要实现的是将信标添加到监视器,并每秒获取其信标的当前状态以使用 SwiftUI 显示。但是,我不确定这是否是初始化 CLMonitor 的最佳方法,因为 addToMonitor 在 CLMonitor 初始化之前被调用。
我该如何解决这个问题?
对我来说,你似乎试图“拉动”信标的状态。我建议不要这样做。
CLMonitor
有一个名为 events
的异步序列,可以将其设置为“观察”信标状态的变化。
根据此 wwdc 视频,如果您观察到更改,则最新状态只会填充最新值。所以你应该在申请开始后就开始观察。
一个更一般的例子来说明这是如何工作的:
// add the async Stream observer
do{
for try await event in await monitor.events{
if let monitoredRecord = await self.monitor.record(for: identifier) {
let lastEvent = monitoredRecord.lastEvent
// manipulate the model according to the last Event
}
}
} catch{
}