具有 "When In Use" 位置访问错误代码 4 的 CLLocationManager requestStateForRegion

CLLocationManager requestStateForRegion with "When In Use" location access error code 4

我正在尝试为 iOS 应用实施 iBeacon 测距。

[locationManager requestAlwaysAuthorization];
CLBeaconRegion * region = [self regionFromUUID:uuid];
[locationManager startMonitoringForRegion:region];

为了判断设备是在区域内还是区域外:

- (void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region
{
    [locationManager requestStateForRegion:region];
}

这成功调用了:

- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region {
    if (state == CLRegionStateInside) {
        [locationManager startRangingBeaconsInRegion:(CLBeaconRegion*)region];
    } else {
        [locationManager stopRangingBeaconsInRegion:(CLBeaconRegion*)region];
    }
}

应用程序已成功运行 locationManager:didRangeBeacons:inRegion:

我遇到的问题是使用requestWhenInUseAuthorizationlocationManager:didStartMonitoringForRegion:调用[location requestStateForRegion:region]后,委托方法locationManager:monitoringDidFailForRegion:withError:returns错误码4:"The operation couldn’t be completed"。

startRangingBeaconsInRegion 交换 requestStateForRegion 似乎可以绕过这个错误并且 locationManager:didRangeBeacons:inRegion: 被成功调用。

如果仅授予 kCLAuthorizationStatusAuthorizedWhenInUse[locationManager requestStateForRegion:region]; 会导致错误代码 4,这是已知问题吗?

核心位置监控需要 "always" 授权,即使您只是在应用处于活动状态时尝试进行监控。由于 requestStateForRegion 是监控 API 的一部分,它可以解释为什么在 "when in use" 授权时会抛出监控错误。

我能想到的唯一解决方法是,在 "when in use" 授权时,立即开始测距并使用测距结果而不是 requestStateForRegion 来确定您是在范围内还是范围外给定的信标。

Region Monitoring 的 Apple 文档因以下摘录而困扰我:

If the authorization status is kCLAuthorizationStatusAuthorized, your app can receive boundary crossing notifications for any regions it registered. If the authorization status is set to any other value, the app doesn’t receive those notifications.

我在想 kCLAuthorizationStatusAuthorized(在 iOS 8 中弃用)将包括 kCLAuthorizationStatusAuthorizedAlwayskCLAuthorizationStatusAuthorizedWhenInUse,因为它们都是 "Authorized" 的特殊类型。

感谢@heypiotr,我决定实际查看 Apple Docs Declaration 并注意到枚举声明如下:

kCLAuthorizationStatusAuthorized,
kCLAuthorizationStatusAuthorizedAlways = kCLAuthorizationStatusAuthorized,
kCLAuthorizationStatusAuthorizedWhenInUse 

因此,requestStateForRegion 需要 kCLAuthorizationStatusAuthorizedAlways,因为这是唯一与 kCLAuthorizationStatusAuthorized 相同的值,而且根据 Apple 的说法,只有 kCLAuthorizationStatusAuthorized 可以用于监控.