在 Swift 中处理异步函数

问题描述 投票:0回答:1

我正在尝试实施 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 初始化之前被调用。

我该如何解决这个问题?

swift swiftui async-await core-location ibeacon
1个回答
0
投票

对我来说,你似乎试图“拉动”信标的状态。我建议不要这样做。

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{
    
}
© www.soinside.com 2019 - 2024. All rights reserved.