我正在尝试为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:
一起前进。
我遇到的问题是使用requestWhenInUseAuthorization
.[location requestStateForRegion:region]
locationManager:didStartMonitoringForRegion:
调用后,委托方法locationManager:monitoringDidFailForRegion:withError:
返回错误代码 4:"无法完成操作"。
与startRangingBeaconsInRegion
交换requestStateForRegion
似乎绕过了此错误,并且成功调用了locationManager:didRangeBeacons:inRegion:
。
这是一个已知问题,如果仅授予kCLAuthorizationStatusAuthorizedWhenInUse
,[locationManager requestStateForRegion:region];
将导致错误代码 4?
用于区域监控的Apple文档为以下摘录困扰着我:
如果授权状态为 kCLAuthorizationStatusAuthorized,则应用可以接收其注册的任何区域的边界交叉通知。如果授权状态设置为任何其他值,则应用不会收到这些通知。
我在想kCLAuthorizationStatusAuthorized
(在iOS 8中已弃用)将包括kCLAuthorizationStatusAuthorizedAlways
和kCLAuthorizationStatusAuthorizedWhenInUse
,因为它们都是特殊类型的"授权"。
多亏了@heypiotr,我决定实际查看 Apple Docs 声明,并注意到枚举声明以下内容:
kCLAuthorizationStatusAuthorized,
kCLAuthorizationStatusAuthorizedAlways = kCLAuthorizationStatusAuthorized,
kCLAuthorizationStatusAuthorizedWhenInUse
因此,requestStateForRegion
需要kCLAuthorizationStatusAuthorizedAlways
,因为这是唯一与 kCLAuthorizationStatusAuthorized
相同的值 ,并且根据Apple的说法,只有kCLAuthorizationStatusAuthorized
才能与监视一起使用。
核心位置监视需要"始终"授权,即使你仅在应用处于活动状态时尝试执行监视也是如此。由于requestStateForRegion
是监视 API 的一部分,因此它将解释为什么它在"使用时"授权时会引发监视错误。
我能想到的唯一解决方法是, 当处于"使用时"授权时, 立即开始测距并使用测距结果而不是requestStateForRegion
来确定您是在给定信标的范围内还是之外.