目标C语言 iOS 7 CoreLocation:定位服务授权后第一次区域监控失败



我在使用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漏洞类似,它只是在某些设备上随机停止工作。我试着重新启动蓝牙,没有任何帮助。

不知道是什么改变了,但我第二天又试了一次,它开始工作了。

基本上你可能需要尝试不同的设备,直到这个设备重新开始工作。

相关内容

  • 没有找到相关文章

最新更新