いよいよジオフェンシングの実装へ

前置きが長くなったが、いよいよジオフェンシングの実装である。

iOSにおけるジオフェンシング機能はCore Locationフレームワークの一部として提供されるものだ。同フレームワークの中心的なクラスであるCLLocationManagerクラスのオブジェクトに対してジオフェンシングの範囲を設定することで、有効化する。

CLManagerの初期設定をリスト4に示す。

リスト4

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  self.locationManager = [[CLLocationManager alloc] init];
  self.locationManager.delegate = self;
  [self.locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
  [self.locationManager setDistanceFilter:kCLDistanceFilterNone];
  [self.locationManager startUpdatingLocation];

  return YES;
}

今回の例ではアプリケーションデリゲートにCLManagerインスタンスの保持・管理を実装する方針とした。このためapplication:didFinishLaunchingWithOptions:でCLLocationManagerの初期化を行い、デリゲートメソッドの呼び出し先をアプリケーションデリゲート自身となるよう設定している。

こうして作成したCLLocationManagerインスタンスにジオフェンシングの範囲を設定するには、CLRegionクラスのインスタンスにジオフェンシング範囲の中心座標と、その座標を中心とする円形領域の半径の長さを指定する。

CLLocationManagerのstartMonitoringForRegionを呼び出せば、システムにジオフェンシング範囲が設定されて、ジオフェンシングが有効となる。

ジオフェンシング範囲は1つのアプリにつき複数指定することが可能である。これらはCLRegionのidentifierプロパティに一意の文字列を設定することで識別することができる。(リスト5)

リスト5

    CLLocationCoordinate2D coordinate
      = CLLocationCoordinate2DMake(35.71014, 139.81085);

    CLLocationDistance radiusOnMeter = 100.0;

    CLRegion *grRegion = [[CLRegion alloc] initCircularRegionWithCenter:coordinate radius:radiusOnMeter identifier:@"Tokyo-SkyTree"];
    [self.locationManager startMonitoringForRegion:grRegion];

ユーザの端末がジオフェンス範囲に入った、もしくは範囲から出た時点で起動する処理を記述するには、CLLocationManagerのデリゲートプロトコルで定義されているlocationManager:didEnterRegion:、もしくはlocationManager:didExitRegion:を実装する。前述のように、ジオフェンシング範囲を複数設定した場合は、同メソッドの引数として渡されるCLRegionのインスタンスのidentifierプロパティを用いて識別する。(リスト6)

リスト6

- (void)locationManager:(CLLocationManager *)manager didEnterRegion:(CLRegion *)region
{
    NSLog(@"ジオフェンス領域%@に入りました",region.identifier);

}

- (void)locationManager:(CLLocationManager *)manager didExitRegion:(CLRegion *)region
{
    NSLog(@"ジオフェンス領域%@から出ました",region.identifier);
}

ジオフェンスの基本的な実装はこれだけだ。簡単に利用できることがおわかりいただけるだろう。

プログラミングTips

実装方法の解説は以上だが、ついでにSweetHomeの開発を通じて得たTIPSを3つほど紹介しておこう。

iOSシミュレータに便利なデバッグ機能が

iOSシミュレータを用いて、ジオフェンシング機能を用いるアプリをテスト・デバッグすることが可能だ。iOSシミュレータの[デバッグ]メニューから、[位置]→[位置情報をカスタマイズ...]を選ぶと図3のようなウインドウが出る。

図3 : 位置情報のウィンドウが登場

このウインドウの緯度・経度を変更することで、iOSデバイスの仮想的な位置を変更できる。この設定をアプリの実行中に変更すれば実機と同様、ジオフェンシング機能が作動する。

領域設定では、下限と認識誤差を意識しよう

SweetHomeアプリを開発するに当たり、我々が行ったフィールドテストの結果では、アプリに設定するジオフェンス領域の半径は100mを下限とするのが実用的であった。100m未満に設定すると、認識誤差の影響でジオフェンス領域への出入りを誤認識して頻繁に処理が作動してしまった。また、動作の誤差は設定した半径の±10-30m程度で動作することを目安にしてサービス設計を行うのが良さそうである。

なお、ジオフェンス領域内から地下鉄に乗るなどすると、ジオフェンシングが作動する地点が大きくずれることがあるので注意が必要である。

気になる電力消費量の増減は?

我々がジオフェンシング対応アプリを開発する上での最大の懸念点が、電池の消費量であった。しかし、24時間ジオフェンシングを有効にしていても、目に見えて電池の減りが早くなるということは無く、十分に実用に耐えうるものとなった。

最後になったが、本稿のサンプルプログラムは、GitHubで公開している。参考にしていただければ幸いだ。

執筆者紹介

ponpoko1968

KLab株式会社 開発制作本部 データ分析グループ所属。セキュリティ関連のソフトハウスに勤務後、現職。電子マネー関連システム、金融系携帯アプリの開発などを経て、エンタメ系iOSアプリや「SweetHome」の開発に携わる。

現在はソーシャルゲームのデータマイニングを担当している。また、個人でもiOS向け電子書籍リーダアプリなどをリリースしている。