从位置管理器请求状态时CLRegionState是未知的?

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

我正在构建一个与区域监控相关的功能,同时开始区域监控我正在请求状态,如下面的代码所示。在某些设备上,我一直在获得区域状态未知。如果我打开或关闭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)")
}
ios core-location
2个回答
4
投票

问题是,你使用硬编码延迟调用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)
   }
}

0
投票

来自CLLocationManager requestState(for:) docs

region:您想知道其状态的区域。此对象必须是Map Kit提供的标准区域子类之一的实例。您无法使用此方法来确定自己定义的自定义区域的状态。

您自己定义了该区域,因此您无法使用requestState(for:)来获取其状态。您可以将该函数用于从Core Location返回的区域(通过委托方法)。

如果您想知道设备当前是否在某个区域内,请启动标准位置更新请求(startUpdatingLocation()等),当您返回最近且准确的坐标时,请使用CLCircularRegion contains()函数检查坐标。

// In the locationManager(_:didUpdateLocations:) delegate method
if myCircularRegion.contains(myCoordinate) {
    // ...
}
© www.soinside.com 2019 - 2024. All rights reserved.