4

ユーザーが家を出るたびに警告する小さなジオフェンス(100メートル)をセットアップしようとしています。これを行うには、次のようにユーザーに現在の場所を要求します。

- (void)requestUsersCurrentLocation
{
    if (self.locationManager == nil) self.locationManager = [[CLLocationManager alloc] init];

    self.locationManager.delegate = self;
    self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
    self.locationManager.distanceFilter = 100;
    [self.locationManager startUpdatingLocation];
}

CLLocationManagerのデリゲートメソッドを使用して、アプリケーションがユーザーの現在の場所を特定できたかどうかを確認します。attemptToRegisterGeofenceAlertForLocation:私のテストでは、これは正しく機能し、アプリケーションは私のメソッドの呼び出しに進みます

- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
    CLLocation *location = [locations lastObject];
    NSDate *eventDate = location.timestamp;
    NSTimeInterval howRecent = [eventDate timeIntervalSinceNow];
    if (abs(howRecent) < 15.0)
    {
        [self.locationManager stopUpdatingLocation];

        if([self attemptToRegisterGeofenceAlertForLocation:location])
        {
            [[NSNotificationCenter defaultCenter] postNotificationName:kGeofenceSetupSuccess object:nil];
        }
        else
        {
            [[NSNotificationCenter defaultCenter] postNotificationName:kGeofenceSetupFailure object:nil];
        }
    }
}

ここまでは順調ですね。これが、ユーザーの現在の場所の周りに比較的小さなジオフェンスを登録するための私のカスタム関数です。

- (BOOL)attemptToRegisterGeofenceAlertForLocation:(CLLocation *)location
{
    // Do not create regions if support is unavailable or disabled
    if (![CLLocationManager regionMonitoringAvailable]) return NO;

    // Check the authorization status
    if (([CLLocationManager authorizationStatus] != kCLAuthorizationStatusAuthorized) && ([CLLocationManager authorizationStatus] != kCLAuthorizationStatusNotDetermined)) return NO;

    // Clear out any old regions to prevent buildup.
    if ([self.locationManager.monitoredRegions count] > 0)
    {
        for (id obj in self.locationManager.monitoredRegions)
        {
            [self.locationManager stopMonitoringForRegion:obj];
        }
    }

    // If the overlay's radius is too large, registration fails automatically,
    // so clamp the radius to the max value.
    CLLocationDegrees radius = 100; // meters?
    if (radius > self.locationManager.maximumRegionMonitoringDistance)
    {
        radius = self.locationManager.maximumRegionMonitoringDistance;
    }

    // Create the region to be monitored.
    CLRegion *region = [[CLRegion alloc] initCircularRegionWithCenter:location.coordinate radius:radius identifier:kGeofenceIdentifier];
    [self.locationManager startMonitoringForRegion:region];

    return YES;
}

ユーザーがジオフェンス領域を終了すると、次のように応答します。

- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
    if([region.identifier isEqual:kGeofenceIdentifier])
    {
        if([[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground)
        {
            // Fire a UILocationNotification
        }
        else
        {
            // Fire a UIAlertView
        }
    }
}

アプリケーションがユーザーの場所を取得でき、ジオフェンスが正しく登録されていると判断しましたが、実際のデバイス(3G対応のiPhone)でトリガーすることはできません。私はジオフェンス地域を離れ、何の通知も受け取らずに数マイル移動しました。場所を大幅に変更することで、シミュレーターでアラートを受信することに成功しました。

私は何が間違っているのですか?

4

3 に答える 3

1

半径が100M(良好)に設定されているようです。距離フィルターも100Mに設定されているので、あなたと戦っている可能性があります。シミュレーターでは、それらを渡す必要があるため、非常に正確な更新を取得します。実際のテストでは、Wifi近似とセル三角測量から取得する座標は正確ではありません。

私の経験ではkCLLocationAccuracyBest、距離フィルターに使用すると、非常に良い結果が得られます。リージョンモニタリングはシステムからすでに低電力であるため、フィルターを最適に設定するだけでバッテリーがヒットすることはありません。

于 2013-01-02T20:44:31.363 に答える
1

この問題の解決策は、CLLocationManagerがメインスレッドで初期化されていることを確認することでした。Appleのドキュメントによると:

ロケーションマネージャーオブジェクトの構成は、アプリケーションのメインスレッドなど、実行ループがアクティブなスレッドで常に行う必要があります。

于 2017-04-30T12:41:47.403 に答える
0

あなたはすでにあなたの答えを持っています、しかし時々問題はあまり外出せず、あまり長く留まらないこと、あるいはあなたがそれをしたことが原因かもしれません、しかしあなたは地域なので非常に小さなものに設定されたようなものでした5メートル(絶対にやるべきではないこと)そしてあなたは100メートルのように移動しました

iOSシミュレーターまたはデバイスでリージョン監視コードをテストするときは、リージョンの境界を超えた直後にリージョンイベントが発生しない可能性があることに注意してください。誤った通知を防ぐために、iOSは、特定のしきい値条件が満たされるまでリージョン通知を配信しません。具体的には、ユーザーの位置は、地域の境界を越え、境界から最小距離だけ離れ、通知が報告される前に少なくとも20秒間その最小距離に留まる必要があります。

特定のしきい値距離は、現在利用可能なハードウェアとロケーションテクノロジーによって決定されます。たとえば、 Wi -Fiが無効になっている場合、地域の監視の精度は大幅に低下します。ただし、テストの目的で、最小距離は約200メートルであると想定できます 。

Appleのドキュメントから:Region Monitoring

于 2017-07-28T14:28:07.813 に答える