9

アプリが実行中で、CLLocationManagerDelegateクラスがフォアグラウンド(つまり表示)の場合、didEnterRegionsがトリガーされ、NSLogとAlertViewの両方が取得されます。ただし、アプリがバックグラウンドにある場合、または基本的に、画面にデリゲートクラス以外のものが表示されている場合は、何も表示されません。

plistの「必要なバックグラウンドモード」の下に「位置情報の更新用のアプリレジスタ」を設定しましたが、それが必要かどうかはわかりません。

私が間違っているかもしれませんが(そして喜んでさらに追加します)、これが関連するコードだと私が思うものです。viewDidLoad内のすべてが、リージョン監視が使用可能で有効になっているかどうかをチェックするifにラップされていることに注意してください。

- (void)viewDidLoad
{
    NSLog(@"MapViewController - viewDidLoad");
    self.locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
    self.locationManager.distanceFilter = kCLLocationAccuracyNearestTenMeters;    
    self.locationManager.delegate = self;
    [self.locationManager startMonitoringSignificantLocationChanges];
}

- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
    NSLog(@"MapViewController - didEnterRegion");
    NSLog(@"MVC - didEnterRegion - region.radius = %f", region.radius);
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"entered region..." message:@"You have Entered the Location." delegate:nil cancelButtonTitle:@"OK"  otherButtonTitles: nil];
    alert.tag = 2;
    [alert show];
}

ここで、AppDelegate.mで監視されているリージョンのリストを取得します。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{

// other code

NSLog(@"LISTING ALL REGIONS MONITORED");
    NSArray *regions = [self.locationManager.monitoredRegions allObjects];
    if (!regions) {
        NSLog(@"no regions found");
    } else {
        NSLog(@"got %d monitored regions", [regions count]);
        for (int i = 0; i < [regions count]; i++) {
            CLRegion *region = [regions objectAtIndex:i];
            NSLog(@"region %d's identifier = %@", i, region.identifier);
            NSLog(@"region: radius: %@", region.radius);
        }
    }

// other code
}

startMonitoringForRegionを2回呼び出します。主な場所は、次のとおりです。

- (void)doneButtonTapped {
    NSLog(@"doneButtonTapped");

    if (self.locationIdentifier) {
        if ([CLLocationManager regionMonitoringEnabled] && [CLLocationManager regionMonitoringAvailable]) {

            // core data setup
            NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
            NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"LocationReminder" inManagedObjectContext:self.managedObjectContext];
            fetchRequest.entity = entityDescription;
            NSPredicate *predicate = [NSPredicate predicateWithFormat:@"locationIdentifier == %@", self.locationIdentifier];
            fetchRequest.predicate = predicate;
            NSError *error;
            NSArray *results = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
            if (results) {

                // get the LocationReminder
                LocationReminder *retrievedReminder = [results objectAtIndex:0];
                retrievedReminder.audioURI = [[[self.audioPlayers objectAtIndex:self.selectedCell] url] absoluteString];
                retrievedReminder.userRecording = nil;

                // start monitoring it's region
                NSArray *coordinateArray = [retrievedReminder.locationIdentifier componentsSeparatedByString:@", "];
                CLLocationCoordinate2D coordinate = {[[coordinateArray objectAtIndex:0] doubleValue], [[coordinateArray objectAtIndex:1] doubleValue]};
                CLRegion *newRegion = [[CLRegion alloc] initCircularRegionWithCenter:coordinate radius:250.0 identifier:retrievedReminder.locationIdentifier];
                NSLog(@"about to monitor region with radius: %f", newRegion.radius);
                [self.locationManager startMonitoringForRegion:newRegion desiredAccuracy:kCLLocationAccuracyBest];

                // save the LocationReminder
                if (![self.managedObjectContext save:&error]) {
                    NSLog(@"hmm.  no managed object context.  must be something space-time going on");
                } else {
                    NSLog(@"saved locationReminder, locationIdentifier = %@", retrievedReminder.locationIdentifier);
                }
            } else {
                NSLog(@"ERROR: no LocationReminder retreived for predicate: %@", predicate);
            }
        }

        // get the mapview controller off of the navigation stack
        for (UIViewController *viewController in self.navigationController.viewControllers) {
            if ([viewController isKindOfClass:[MapViewController class]]) { 
                MapViewController *mapVC = (MapViewController *)viewController;
                mapVC.audioURI = [[[self.audioPlayers objectAtIndex:self.selectedCell] url] absoluteString];
                [self.navigationController popToViewController:mapVC animated:YES];
            }
        }
}

そして、それが重要かもしれないと感じたので、locationManagerのゲッターは次のとおりです。

- (CLLocationManager *)locationManager {
    NSLog(@"MapViewController - locationManager");
    if (_locationManager) {
        return _locationManager;
    } else {
        _locationManager = [[CLLocationManager alloc] init];
        return _locationManager;
    }
}

更新1: Appleフォーラム(私がクロスポストした場所)を介して、AlertViewはフォアグラウンドでのみ表示されると誰かが言った。それでもNSLogは起動しません。私はそれがうまくいくと思います。

4

4 に答える 4

2

私の友人は、あなたが抱えているいくつかの問題を解決するのに役立つかもしれないジオフェンスの使用に関する素晴らしいチュートリアルを書きました。

ジオフェンスを始めましょう

オンラインとここSOにはたくさんの例があります。小さなことから始めて、上に向かって進んでください。コールバックの取得を開始したら、他のViewControllerに拡張を開始できます。

アップデート

コメントで説明されているように、ロケーションマネージャーとデリゲートメソッドを制御するシングルトンクラスを作成することの利点。シングルトンを使用することで、デリゲートメソッドへの複数の呼び出しが発生する可能性を防ぎます。注意深くコーディングすることでこれを防ぐことができますが、シングルトンを使用することでこれを行うことができます。これは、デリゲートメソッドで実行する必要のあるすべての作業を処理するための優れたクラスでもあります。

于 2012-09-12T13:06:17.383 に答える
2

あなたが間違っていること:

  1. バックグラウンドモード-アプリは位置情報の更新を登録します。これは必要ありません。これは、場所などの大幅な変更に関する情報を収集する場合に必要です。したがって、[ターゲット]>[アプリ]>[機能]に移動し、[バックグラウンドモード]で目的のオプションを選択します。これにより、plistが自動的に更新されます。今のところ、無効にします。
  2. ユーザーがリージョンに入ったときにアラートを作成しようとしています。これはアプリが動作しているときに動作している間、アプリがバックグラウンドにあるときはアラートは役に立ちません。実行-ローカル通知またはAPI呼び出しをトリガーします

例えば。通知の:

    -(void)triggerLocalNotification:(CLRegion *)region{
    UILocalNotification *notification = [[UILocalNotification alloc]init];
    [notification setAlertBody:[NSString stringWithFormat:@"Welcome to %@", [region identifier]]];
    [notification setRepeatInterval:0];
    [notification setFireDate:[NSDate dateWithTimeIntervalSinceNow:2]];
    [notification setTimeZone:[NSTimeZone  defaultTimeZone]];
    [[UIApplication sharedApplication]scheduleLocalNotification:notification];
    NSLog(@"notification triggered with notification %@", notification);
}
于 2015-03-11T06:40:28.173 に答える
0

あなたがdidEnterRegionしたときにローカル通知を投稿することができます。

これにより、バックグラウンドにいる場合でもアラートのようなポップアップが表示されます。

簡単なテストを行うことができます:

1)アプリデリゲートのapplicationDidEnterBackground内に、ランダムなメッセージを含むローカル通知オブジェクトを作成し、ローカル通知にすぐに起動するように指示します。

2)ホームボタンを押します。アプリを最小化すると、ポップアップが表示されます。

于 2012-09-12T04:35:08.550 に答える
0

app.plistにアクセスする必要があると思います

必要なバックグラウンドモードを追加します:位置更新のためにitmeアプリレジスタを追加します

および1。アプリがバックグラウンドにある場合でも、上部に矢印が表示されます

2、アプリが強制終了された場合でも、上部に中空の矢印が表示されます。iOSはリージョンを監視しますが、リージョンは20に制限されます。

于 2013-09-03T05:40:28.677 に答える