我在使用CoreLocation时发现了一个奇怪的行为。我正在使用区域监控功能,但是,在授权位置服务(通过弹出窗口或设置->位置服务)后,区域监控失败(操作无法完成)。kCLErrorDomain错误5.)如果我关闭应用程序并重新启动(因此已经授权),一切都按预期工作。我的代码是这样的:
-(void)initializeLocationServices
{
NSLog(@"Started location services");
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
locationManager.pausesLocationUpdatesAutomatically = NO;
[locationManager startUpdatingLocation]; // to show authorisation popup
}
-(CLCircularRegion*)createRegion
{
// Test coordinates
CLLocationDegrees latitude = 50;
CLLocationDegrees longitude = -1;
CLLocationDistance radius = 50; // meters;
// If radius is too large, registration fails automatically, so limit the radius to the maximum value
if (radius > locationManager.maximumRegionMonitoringDistance) {
radius = locationManager.maximumRegionMonitoringDistance;
}
CLCircularRegion* region = [[CLCircularRegion alloc] initWithCenter:CLLocationCoordinate2DMake(latitude, longitude) radius:radius identifier:@"TEST"];
region.notifyOnEntry = YES;
region.notifyOnExit = YES;
NSLog(@"Created region");
return region;
}
-(void)monitorProximity
{
CLRegion *region = [self createRegion];
// Check if support is unavailable
if ( ![CLLocationManager isMonitoringAvailableForClass:[CLRegion class]]) {
NSLog( @"Failed to initialise region monitoring: support unavailable");
return;
}
// Check if authorised
if ([CLLocationManager authorizationStatus] != kCLAuthorizationStatusAuthorized) {
NSLog( @"Failed to initialise region monitoring: app not authorized to use location services");
return;
} else {
NSLog(@"Started monitoring proximity");
}
// Clear out any old regions to prevent buildup.
if ([locationManager.monitoredRegions count] > 0) {
for (id obj in locationManager.monitoredRegions)
[locationManager stopMonitoringForRegion:obj];
}
[locationManager startMonitoringForRegion:region];
}
-(void)locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region
{
NSLog(@"Started monitoring for region: %@", [region description]);
[locationManager requestStateForRegion:region]; // check if already inside region
}
-(void)locationManager:(CLLocationManager *)manager monitoringDidFailForRegion:(CLRegion *)region withError:(NSError *)error
{
NSLog(@"Failed to start monitoring for region: %@", [error localizedDescription]);
}
-(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
{
NSLog(@"didDetermineState");
if (state == CLRegionStateInside) {
NSLog(@"inside");
return;
} else if (state == CLRegionStateOutside) {
NSLog(@"outside");
} else {
NSLog(@"unknown");
}
}
-(void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
NSLog(@"didEnterRegion");
}
-(void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
NSLog(@"didExitRegion");
}
-(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
NSLog(@"Monitoring authorisation status is now: %@", status == kCLAuthorizationStatusAuthorized ? @"authorized" : @"not authorized");
if (status == kCLAuthorizationStatusAuthorized) {
[self monitorProximity];
}
}
我在这里做错了什么吗?在didChangeAuthorizationStatus被调用后,我是否有问题?
从其他用户报告来看,kCLErrorDomain 5
似乎是区域监控失败的"一锅端";它没有提供太多有用的信息。我认为您的问题是由
[locationManager requestStateForRegion:region]; // check if already inside region
从委托方法didStartMonitoringForRegion:
中调用
我在自己的项目中看到了非常相似的东西,并将这一行删除(或延迟执行一段时间)解决了问题。我最好的猜测是,当这个委托方法触发时,iOS仍然在运行一些内部区域监控代码,所以现在不是调用requestStateForRegion:
试着把这个拿出来看看是不是答案
kCLErrorDomain代码/错误5意味着您已经尝试监视超过20个CLRegions。这里Descriptio
参见startMonitoringForRegion描述,上面写着:
一个应用程序一次最多可以注册20个地区。
kCLErrorDomain
5
是一个集合,可以表示许多不同的含义。
其中一个来源是当你调用[locationManager requestStateForRegion:region]
时,这是必要的,当你第一次监视一个地区,以知道你是否已经在该地区。这是因为didEnter区域只有在实际进入该区域时才会被调用。通常,这意味着您第一次监视该区域时,您必须等待5秒,直到该区域未被检测到,然后才会在下次您在该区域时触发该区域。
关于这个问题的原因有许多不同的报告:
- 确保被监测的信标不超过20个
-
5
表示"regionMonitoringFailure"。确保半径不太大(与信标监控无关)。 - 确保位置更新已注册
- 省略调用requestStateForRegion,但是我在上面描述了为什么有必要这样做。
- 重启设备和蓝牙可能有帮助 尝试30秒延迟
然而,这些都不适合我。我认为我的根本原因与iOS 7.1漏洞类似,它只是在某些设备上随机停止工作。我试着重新启动蓝牙,没有任何帮助。
不知道是什么改变了,但我第二天又试了一次,它开始工作了。
基本上你可能需要尝试不同的设备,直到这个设备重新开始工作。