web-dev-qa-db-ja.com

iOSで地理ベースのプッシュ通知を使用する方法

(バックグラウンドではなく)アプリケーションが強制終了されたときにiOSで地理ベースのプッシュ通知を利用することは可能ですか?

ユーザーが地図上の位置を選択するアプリを作成することに興味があります。たとえば、ユーザーがそのエリアに近い場合、ローカルの地理ベースのプッシュ通知がトリガーされます。

しかし、この「アイデア」は可能ですか? GPSを実行して、アプリが強制終了されたときに座標を比較して実行し、配置されているときにユーザーに通知できますか?私が読むことができる主題に関するチュートリアル/記事/その他の種類の情報はありますか?

私がオンラインで読んだ情報のほとんどは、問題について何も特定せずに実装するという一般的なアイデアのようなものでした。

24
donparalias

アプリが実行されていない(つまり、以前に終了されている)ときにユーザーの位置を追跡するには、2つのオプションがあります。

  1. iOSアプリプログラミングガイド の「ユーザーの場所の追跡」の下:

    重要な変更の位置情報サービスは、高精度の位置情報を必要としないアプリに強く推奨されます。このサービスでは、ユーザーの現在地が大幅に変更された場合にのみ、現在地の更新が生成されます。したがって、ソーシャルアプリや、重要ではない場所関連の情報をユーザーに提供するアプリに最適です。更新が発生したときにアプリが一時停止されている場合、システムは更新を処理するためにバックグラウンドで起動します。 アプリがこのサービスを開始して終了した場合、新しい場所が利用可能になると、システムによってアプリが自動的に再起動されます。このサービスはiOS 4以降で利用でき、携帯電話を搭載したデバイスでのみ利用できます。

    ただし、 CLLocationManagerクラスリファレンス によると、これはあまり正確ではなく、更新は頻繁ではありません。

    注:アプリは、デバイスが以前の通知から500メートル以上移動するとすぐに通知を受け取ることができます。 5分ごとに1回よりも頻繁に通知を受け取るべきではありません。デバイスがネットワークからデータを取得できる場合、ロケーションマネージャは通知をタイムリーに配信する可能性がはるかに高くなります。

  2. リージョンモニタリング は、終了後にアプリを再起動することを含め、同様の方法で機能しますが、より高い精度を備えています(Wifiネットワークとセルタワーの可用性によって異なります)。

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

    別の領域監視の考慮事項は、( CLLocationManagerクラス参照 に従って)領域の入口と出口の通知が、領域の境界を超えてから3〜5分程度しか受信されない可能性があることです。

    実際の要件によっては、地域の監視を使用して「大まかな」場所を取得し、ユーザーが特定の地域内にいるときに、ロケーションマネージャーでより正確なGPSベースのサービスを起動できます。ユーザーが関心のある地域を離れたら、GPSサービスをオフにしてバッテリーを節約し、大まかな位置監視サービス(つまり、地域の監視)にもう一度戻します。基本的な実装は次のとおりです。

    SomeViewController.m

    ...
    @interface SomeViewController () <CLLocationManagerDelegate>
    
    @property (nonatomic, strong) CLLocationManager *locationManager;
    @property (nonatomic, strong) CLRegion *someRegion;
    
    @end
    
    @implementation SomeViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        self.locationManager = [[CLLocationManager alloc] init];
    
        CLLocationDistance radius = 10; // 10 metre sensitivity
        self.someRegion = [[CLRegion alloc] initCircularRegionWithCenter:someCoordinates radius:radius identifier:@"Smithtown Dry Cleaners"];
    
        self.locationManager.delegate = self;
        [self.locationManager startMonitoringForRegion:self.someRegion];
    
        self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
        self.locationManager.distanceFilter = 10;
        [self.locationManager startUpdatingLocation];
    }
    
    - (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
    {
        [self.locationManager startUpdatingLocation];
    }
    
    - (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
    {
        [self.locationManager stopUpdatingLocation];
    }
    
    // Delegate method from the CLLocationManagerDelegate protocol.
    - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
    {
        CLLocation* location = [locations lastObject];
    
        // If the user's current location is not within the region anymore, stop updating
        if ([self.someRegion containsCoordinate:location.coordinate] == NO) {
            [self.locationManager stopUpdatingLocation];
        }
    
        NSString *locationData = [NSString stringWithFormat:@"latitude %+.6f, longitude %+.6f\n",
                                  location.coordinate.latitude,
                                  location.coordinate.longitude];
        NSLog(@"%@", locationData);
    
        UILocalNotification *localNotification = [[UILocalNotification alloc] init];
        localNotification.alertBody = locationData;
        localNotification.alertAction = @"Location data received";
        localNotification.hasAction = YES;
        [[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
    }
    

    アプリケーションのplistファイルに適切なエントリを追加して、適切なリソースにアクセスできるようにアプリをバックグラウンドで実行することを忘れないでください。

    MyApp-Info.plist

    <key>UIBackgroundModes</key>
    <array>
            ...
            <string>location</string>
    </array>
    <key>UIRequiredDeviceCapabilities</key>
    <array>
            ...
            <string>location-services</string>
            <string>gps</string>
    </array>
    

    上記のコードはiOS6とARCの使用を想定しています

34
gavdotnet