[iBeacon] レンジングによる近接ビーコン検知時の注意点


 

ビーコンの距離測定(レンジング)で近くのビーコンを探す場合のハマりどころの事例です。

最近は実務で Bluetooth Low Energy や iBeacon 関連に携わっていますが「やってみないとわからない」ことも多いので情報として残しておきたいと思います。

この記事は CoreLocation の iBeacon 関連API(ビーコン領域観測&距離測定)についての知識がある方を対象としています。この分野に疎い方はアップルのドキュメント「位置情報とマッププログラミングガイド」を一読されることをおすすめします。
なお、この記事は OS X 10.9.1 & Xcode 5.0.2 & iOS 7.0.4 の環境で確認した内容です。

ビーコン距離測定(レンジング)の挙動

CLLocationManager クラスの startRangingBeaconsInRegion: メソッドでビーコンとの距離測定を開始すると、デリゲートオブジェクトの locationManager:didRangeBeacons:inRegion: メソッド(CLLocationManagerDelegateプロトコル)が約1秒間隔で呼び出されます。
このデリゲートメソッドの第二引数の NSArray オブジェクトには検出された CLBeacon オブジェクトが格納されていますが、格納される順番は、ビーコンとの相対距離が近い順(CLBeacon オブジェクトの accuracy プロパティ値で昇順ソートされた状態)になっています。

もう少し踏み込んだ話

何らかの要因でビーコン信号が受信できなかった場合、CLBeacon オブジェクトの proximity プロパティの値は CLProximityUnknown となります。このとき、RSSI が取れない=距離が決められないため CLBeacon オブジェクトの accuracy の値はマイナス値(これを書いている時点では -1.0)になります。

A negative value in this property signifies that the actual accuracy could not be determined.
CLBeacon Class Reference / accuracyプロパティのDiscussionより引用

前述の通り、デリゲートメソッド第二引数の配列には CLBeacon オブジェクトが accuracy の値でソートされた状態で格納されるため、accuracy の値が小さい CLProximityUnknown のオブジェクトが配列先頭側に詰められます。
結果として配列には CLBeacon オブジェクトが Unknown -> Immediate -> Near -> Farの順に格納されることになります。

問題点と解決策

アップルのドキュメント「位置情報とマッププログラミングガイド」のサンプルコードにあるように、一番近い距離にあるビーコンを取得するために [beacons firstObject] をすると、CLProximityUnknown の CLBeacon オブジェクトが返されることがあるので注意が必要です。

有効なビーコンのみを参照したい場合は、CLProximityUnknown 以外のオブジェクトのみを取り出して使うようにします。以下にコード例を示します。

- (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region
{
  // CLProximityUnknown以外のビーコンだけを取り出す
  NSPredicate *predicate = [NSPredicate predicateWithFormat:@"proximity != %d", CLProximityUnknown];
  NSArray *validBeacons = [beacons filteredArrayUsingPredicate:predicate];
  NSLog(@"%@", [validBeacons firstObject]);
}

余談

CLBeaconオブジェクトの proximity 値が CLProximityUnknown になる状況は、室内+iDeviceビーコンのように安定した環境でテストしている場合にはほとんど発生しませんが、ビーコンの実地テスト時には頻発します。要因はビーコンの電波が受信できなかったり、電波が届く届かないの境界付近にいたり、ビーコン端末のアドバタイズ周期によるものだったりと様々です。
アプリの挙動だけを見ていると裏で何が起きているのか全く分からないため、BLEパケットのスニファやビーコン情報のロギングツール等が必須になります。

 

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください