我正在构建一个与区域监控相关的功能,同时开始区域监控我正在请求状态,如下面的代码所示。在某些设备上,我一直在获得区域状态未知。如果我打开或关闭Wifi或将充电器插入其中。它开始工作正常。如何在蜂窝网络上使其更可靠?请注意,在进行任何区域监视或状态请求调用之前,我已获取用户的所有位置权限。
private func initiateLocationManager() {
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.distanceFilter = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
}
func startMonitoring(alarm: StationAlarm) {
if LocationManager.sharedInstance.isRegionMonitoringAvailable() {
let coordinate = CLLocationCoordinate2D(latitude: stationLatitude, longitude: stationLongitude)
// 1
let region = CLCircularRegion(center: coordinate, radius: CLLocationDistance(radius * 1000), identifier: alarm.alarmId)
// 2
region.notifyOnEntry = true
region.notifyOnExit = false
// 4
locationManager.startMonitoring(for: region)
Utility.delay(0.1) { [weak self] in
self?.locationManager.requestState(for: region)
}
}
}
func locationManager(_: CLLocationManager, didDetermineState state: CLRegionState, for region: CLRegion) {
Log.event("Region State is \(state.rawValue)")
}
问题是,你使用硬编码延迟调用requestState
- (0.1)。如何确保位置管理器在0.1秒内开始监控您的区域?只有在开始监视区域时,您才能获得区域的确切区域状态。
克服这个问题的更好方法是,实现didStartMonitoringForRegion
委托并调用requestStateForRegion
locationManager.startMonitoring(for: region)
func locationManager(_ manager: CLLocationManager, didStartMonitoringFor region: CLRegion) {
manager.requestState(for: region)
}
func locationManager(_ manager: CLLocationManager, didDetermineState state: CLRegionState, for region: CLRegion) {
if (region is CLBeaconRegion) && state == .inside {
locationManager(manager, didEnterRegion: region)
}
}
来自CLLocationManager requestState(for:)
docs:
region:您想知道其状态的区域。此对象必须是Map Kit提供的标准区域子类之一的实例。您无法使用此方法来确定自己定义的自定义区域的状态。
您自己定义了该区域,因此您无法使用requestState(for:)
来获取其状态。您可以将该函数用于从Core Location返回的区域(通过委托方法)。
如果您想知道设备当前是否在某个区域内,请启动标准位置更新请求(startUpdatingLocation()
等),当您返回最近且准确的坐标时,请使用CLCircularRegion
contains()
函数检查坐标。
// In the locationManager(_:didUpdateLocations:) delegate method
if myCircularRegion.contains(myCoordinate) {
// ...
}