iBeacon(1) - はまりポイント無限Ranging

iOS7の新機能、iBeaconがとても面白いので、いろいろ遊んでみています。先月はiBeacon Advent Calendarも開催されて、

iBeacon Advent Calendar 2013

いろいろな情報が集まっていますね。

手元にいくつかiBeaconデバイスを集めてアプリを作っているのですが、いちばんはまったポイントはBluetoothと位置情報のOn/Offのハンドリングです。

iBeaconが動作するための条件

iBeaconが動作するためには、

  • BluetoothがOnになっている
  • 位置情報サービスがOnになっている
  • 位置情報サービスのアプリ項目がOnになっている

の3つの条件が揃っていなければなりません。

このうち、3つめの位置情報サービスのアプリ項目は、アプリをインストールしただけでは項目が作成されず、アプリを立ち上げて実際に位置情報サービスのリクエストをした段階で作成されます。

Requesting Location Services

ここで、「OK」を選択すると位置情報サービスのアプリ項目がOnの状態で、「許可しない」を選択するとOffの状態でアプリ項目が作成されます。

「OK」であれば、そのまま処理を継続すればよいのですが、「許可しない」をユーザーが選択した場合は注意が必要です。また、iBeaconのリージョン監視やレンジングをしている最中に、ユーザー操作によってBluetoothや位置情報関連のOn/Offが行われることもあるので、上記3つの条件が揃っているかどうかをアプリは注意深く監視する必要があります。

無限Ranging問題

また、デバイス監視をすべて実施したとしても、Rangingに関してはアプリ側で最低限のタイムアウト処理を持つか、適切なタイミングでCLLocationManagerDelegateのlocationManager:requestStateForRegionを呼んで最新のリージョン監視状態をアップデートする必要がありそうです。

実際に体験した問題としては、リージョン監視とレンジングの両方を実行中に、

  • アプリをバックグラウンドにする
  • 設定から位置情報サービスのアプリ項目をOffにする
  • iBeaconのリージョン範囲外に出る(かiBeaconの電源をOffにする)
  • 約5分間程度待つ
  • 設定から位置情報サービスのアプリ項目をOnにする
  • アプリをフォアグランドにする

とすると、レンジングの情報のみが延々とアプリに通知されるという事態に遭遇しました。

おそらく、位置情報のアプリ項目Off時でも、リージョン監視やレンジングの設定はそのままデバイスに設定されたままで、リージョンから出たという通知が、設定Offのためアプリに通知されず、レンジングのみが有効な状態になってしまったものと思われます。

位置サービス関連設定のOn/Offは、CLLocationManagerDelegateの、locationManager:didChangeAuthorizationStatusで通知されますが、この通知はアプリがフォアグラウンドの時のみ実施され、バックグランウド中にOn->Off->Onのような操作により、結果的に設定内容が変更されなかった場合は通知自体が行われません。

そのため、アプリにデバイス設定変更が通知されない状態で、リージョン監視情報が抜け落ちるケースがあります。

次回からはその場合も含めて対応できる実装を進めていきたいと思います。