はじめに
最近iBeacon関係のアプリを作る事が多く、そこで得た物を書きたいと思います。
- 内容としては下記です。
- ・対応端末について
- ・OSバージョンでの挙動の違い
- ・ウェイクアップ時について
- ・iOS8対応
- ・複数UUIDのビーコンに反応させる
- ・範囲判定について
小ネタ
■対応端末について(参考)
- iPhone 4s 以降
- iPad (3rd generation) 以降
- iPad mini 以降
- iPod touch (5th generation) 以降
特にiPhone4はiOS7が入りますが、iBeaconには反応しないので注意して下さい。
■OSバージョンでの挙動の違い
7.0から利用可能になったiBeaconは、バージョンアップに連れて改善されています
- 7.0 アプリが起動している時のみ反応、反応精度は悪いです。
- 7.1 バックグラウンドでも反応し、アプリが完全に終了していても反応します。
- 8.0 特に発表されていませんが、体感できるレベルで反応が良くなってます。
■ウェイクアップ時について
・アプリが完全に終了した状態で、iBeaconに反応した時は10秒間だけ動作します。
※beginBackgroundTaskWithExpirationHandlerを行えば、処理を3分間延長できますが 延長できる時間は、フォアグラウンドにならないとリセットされないので、iBeaconとは相性が悪いです。
・その場合はAppDelegateのfinishLaunchingApplicationから動作が始まります。
[launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey]の中身がnilではなくなるので それで通常時と処理を分けます、しかもその場合は、全く何も動いてない状態から始まるので、ビーコン検知処理も記述する必要があります。
■iOS8対応(GPSと同様)
これは検索すればいくらでも出てくるので要点だけさらっと紹介します。
・Info.plistに追記
- NSLocationAlwaysUsageDescription バックグラウンドでも動作する場合
- NSLocationWhenInUseUsageDescription フォアグラウンドのみ動作する場合
※Valueに文字列を書くと、ユーザに位置情報取得許可のダイアログが出た際に表示されます。文字数は200文字程度いけます。
・規約ダイアログの表示
用途によってどちらかを使います。
1 2 |
[locationManager requestAlwaysAuthorization]; [locationManager requestWhenInUseAuthorization]; |
■複数UUIDのビーコンに反応させる
CLBeaconRegionを複数作り、それぞれに対して、startMonitoringForRegionとするだけです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
for (int i = 0 ; i < uuidStringArray.count ; i++) { NSString *strUUID = [uuidStringArray objectAtIndex:i]; CLBeaconRegion *bRegion = [[CLBeaconRegion alloc] initWithProximityUUID:[[NSUUID alloc] initWithUUIDString:strUUID] identifier:[NSString stringWithFormat:@"%@%d", [[NSBundle mainBundle] bundleIdentifier], i]]; if (bRegion == nil) { continue; } bRegion.notifyOnEntry = true; bRegion.notifyOnExit = true; [_beaconRegions addObject:bRegion]; } for (CLBeaconRegion *br in _beaconRegions) { if ([br isMemberOfClass:[CLBeaconRegion class]]) { [self startMonitoringForRegion:br]; } } |
※注意点としては、例えば2つのUUIDを使った場合、1つのビーコンにしか反応してないにも関わらず 2回分の反応イベントが動くので、うまく間引く必要があります。
■範囲判定について
範囲については、Immediate、Near、Far、Unknownがあります。これらはアプリによってNearだったらとか Far以内だったらとか、色々あるので下記のようなメソッドを作ると、判定がサクッと出来て良いです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
// 指定した近接値を含めた内側に、指定したビーコンがいるか + (BOOL) isValidInsideProximity:(int)proximity targetCLBeacon:(CLBeacon*)clBeacon { BOOL result = false; switch (proximity) { case CLProximityImmediate: if (clBeacon.proximity == CLProximityImmediate) { result = true; } break; case CLProximityNear: if (clBeacon.proximity == CLProximityImmediate || clBeacon.proximity == CLProximityNear) { result = true; } break; case CLProximityFar: if (clBeacon.proximity == CLProximityImmediate || clBeacon.proximity == CLProximityNear || clBeacon.proximity == CLProximityFar) { result = true; } break; default: if (clBeacon.proximity == CLProximityImmediate || clBeacon.proximity == CLProximityNear || clBeacon.proximity == CLProximityFar || clBeacon.proximity == CLProximityUnknown) { result = true; } break; } return result; } // 指定した近接値を含めた外側に、指定したビーコンがいるか + (BOOL) isValidOutsideProximity:(int)proximity targetCLBeacon:(CLBeacon*)clBeacon { BOOL result = false; switch (proximity) { case CLProximityImmediate: if (clBeacon.proximity == CLProximityImmediate || clBeacon.proximity == CLProximityNear || clBeacon.proximity == CLProximityFar || clBeacon.proximity == CLProximityUnknown) { result = true; } break; case CLProximityNear: if (clBeacon.proximity == CLProximityNear || clBeacon.proximity == CLProximityFar || clBeacon.proximity == CLProximityUnknown) { result = true; } break; case CLProximityFar: if (clBeacon.proximity == CLProximityFar || clBeacon.proximity == CLProximityUnknown) { result = true; } break; default: if (clBeacon.proximity == CLProximityUnknown) { result = true; } break; } return result; } // 指定した近接値に、指定したビーコンがいるか(そこだけ) + (BOOL) isValidEqualProximity:(int)proximity targetCLBeacon:(CLBeacon*)clBeacon { BOOL result = false; if (proximity == clBeacon.proximity) { result = true; } return result; } |
最後に
iBeaconはハードウェアと環境に左右されるので、扱いが結構大変です、仕様等を把握してないと大変な思いをすることになるので、下記も合わせて読んで頂けたらと思います。