7

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 が呼び出された後のフローに問題はありますか?

4

3 に答える 3

8

他のユーザー レポートからkCLErrorDomain 5、領域監視の失敗の「キャッチ オール」のようです。あまり有益な情報を提供しません。あなたの問題は行によって引き起こされていると思います

[locationManager requestStateForRegion:region]; // check if already inside region

デリゲートメソッド内から呼び出しているものdidStartMonitoringForRegion:

私は自分のプロジェクトで非常によく似たものを見て、この行を削除する (または実行をしばらく遅らせる) ことで問題を解決しました。私の推測では、このデリゲート メソッドが起動されたときに、iOS がまだ何らかの内部領域監視コードを実行しているので、呼び出すのに適切な時期ではありません。requestStateForRegion:

これを取り出してみて、それが答えかどうかを確認してください。

于 2014-09-01T20:24:27.213 に答える
1

kCLErrorDomain コード/エラー 5 は、20 を超える CLRegions を監視しようとしたことを意味します。説明はこちら

startMonitoringForRegionの説明を参照してください
。アプリは一度に最大 20 のリージョンを登録できます。地域の変更をタイムリーに報告するために、地域監視サービスにはネットワーク接続が必要です。

于 2014-03-14T14:29:44.493 に答える
1

kCLErrorDomain 5は、さまざまなことを意味するキャッチ オールです。

ソースの 1 つは[locationManager requestStateForRegion:region]、リージョンを最初に監視して、既にそのリージョンにいるかどうかを確認するときに必要な呼び出しです。これは、実際にリージョンに入ったときにのみ didEnter リージョンが呼び出されるためです。通常、これはリージョンを初めて監視することを意味し、リージョンが検出されなくなるまで 5 秒間待つ必要があり、その後で初めて、次にそのリージョンにいるときに didEnter リージョンが起動します。

問題の原因については、さまざまな報告があります。

しかし、これらのどれも私にとってはうまくいきませんでした。私の根本的な原因は、iOS 7.1 のバグに似ていて、一部のデバイスでランダムに動作しなくなったと思います。Bluetoothの再起動と再起動を試みましたが、何も役に立ちませんでした。

何が変わったのかわかりませんが、翌日もう一度試してみたところ、機能し始めました。

基本的に、このデバイスが再び機能し始めるまで、別のデバイスを試してみることをお勧めします。

于 2018-08-21T05:06:02.530 に答える