iOS 7 CoreLocation:在授权位置服务后,区域监控首次失败

Rui*_*Rui 7 objective-c core-location ios ios7 region-monitoring

我使用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];
    }
}
Run Code Online (Sandbox Code Playgroud)

我在这里做错了吗?调用didChangeAuthorizationStatus后,我的流程有问题吗?

Car*_*s P 7

其他用户报告来看,似乎kCLErrorDomain 5是区域监控失败的"全部捕获"; 它没有提供太多有用的信息.我相信你的问题是由线路造成的

[locationManager requestStateForRegion:region]; // check if already inside region
Run Code Online (Sandbox Code Playgroud)

你在委托方法中调用的 didStartMonitoringForRegion:

我在自己的项目中看到了一些非常相似的东西,并将这一行(或延迟执行一段时间)解决了这个问题.我最好的猜测是,当这个委托方法触发时,iOS仍在运行一些内部区域监控代码,因此现在不适合调用requestStateForRegion:

尝试解决这个问题,看看它是否是答案.

  • 一个简单的方法是使用NSTimer,例如`NSTimer scheduledTimerWithTimeInterval:30.0f target:self selector:@selector(delayMethod)userInfo:nil repeats:NO];`我测试了17个区域,它工作正常,放下在延迟方法中``[locationManager requestStateForRegion:region];` (2认同)

Kos*_*val 1

kCLErrorDomain 代码/错误 5 表示您已尝试监控超过 20 个 CLRegion。描述在这里

请参阅startMonitoringForRegion描述 它说:
一个应用程序一次最多可以注册 20 个区域。为了及时报告区域变化,区域监控服务需要网络连接。