ビーコン メッセージを受信する

アプリは、付近の他のデバイスによってパブリッシュされるメッセージをサブスクライブする場合と同じメカニズムを使用して、Bluetooth Low Energy(BLE)ビーコン メッセージをサブスクライブできます。

デフォルトでは、ビーコンの登録はアプリがフォアグラウンドにある場合にのみ機能します。アプリがバックグラウンドに移行すると、ビーコンのスキャンは自動的に停止されます。バックグラウンド スキャンを有効にする方法については、バックグラウンド スキャンをご覧ください。

ビーコンをサブスクライブするには、subscription パラメータの deviceTypesToDiscover パラメータを kGNSDeviceBLEBeacon に設定します。次のスニペットは、これを行う方法を示しています。

Objective-C

id<GNSSubscription> beaconSubscription = [messageManager
    subscriptionWithMessageFoundHandler:myMessageFoundHandler
                     messageLostHandler:myMessageLostHandler
                            paramsBlock:^(GNSSubscriptionParams *params) {
                              params.deviceTypesToDiscover = kGNSDeviceBLEBeacon;
                            }];

Swift

let beaconSubscription = messageManager.subscriptionWithMessageFoundHandler(
    myMessageFoundHandler, messageLostHandler: myMessageLostHandler,
    paramsBlock: { (params: GNSSubscriptionParams!) in
      params.deviceTypesToDiscover = .BLEBeacon
    })

上記のサブスクリプションでは、プロジェクトが所有するビーコンのみを検出し、それらのビーコンからすべてのメッセージを受信します。別の名前空間で登録されたビーコンからメッセージを受信したい場合は、サブスクリプション パラメータで名前空間を渡すことができます。同様に、特定のタイプのメッセージが必要な場合は、フィルタ用のメッセージ タイプを渡すことができます。次のスニペットは、これを行う方法を示しています。

Objective-C

id<GNSSubscription> beaconSubscription = [messageManager
    subscriptionWithMessageFoundHandler:myMessageFoundHandler
                     messageLostHandler:myMessageLostHandler
                            paramsBlock:^(GNSSubscriptionParams *params) {
                              params.deviceTypesToDiscover = kGNSDeviceBLEBeacon;
                              params.messageNamespace = @"com.mycompany.mybeaconservice";
                              params.type = @"mybeacontype";
                            }];

Swift

let beaconSubscription = messageManager.subscriptionWithMessageFoundHandler(
    myMessageFoundHandler, messageLostHandler: myMessageLostHandler,
    paramsBlock: { (params: GNSSubscriptionParams!) in
      params.deviceTypesToDiscover = .BLEBeacon
      params.messageNamespace = "com.mycompany.mybeaconservice"
      params.type = "mybeacontype"
    })

デフォルトでは、ビーコンの定期購入は Eddystone と iBeacon の両方のタイプのビーコンをスキャンします。iBeacon スキャンを有効にすると、アプリが位置情報を使用する許可を求めるメッセージがユーザーに表示されます。アプリの Info.plist には、位置情報が使用される理由の簡単な説明と NSLocationWhenInUseUsageDescription キーを含める必要があります。詳しくは、Apple のドキュメントをご覧ください。

Eddystone ビーコンのみをスキャンする場合は、GNSBeaconStrategy で iBeacon のスキャンを無効にできます。そうすれば、iOS はユーザーに位置情報の使用許可を求めません。次のスニペットは、上記の元のサブスクリプションの iBeacon スキャンを無効にする方法を示しています。

Objective-C

id<GNSSubscription> beaconSubscription = [messageManager
    subscriptionWithMessageFoundHandler:myMessageFoundHandler
                     messageLostHandler:myMessageLostHandler
                            paramsBlock:^(GNSSubscriptionParams *params) {
                              params.deviceTypesToDiscover = kGNSDeviceBLEBeacon;
                              params.beaconStrategy =
                                  [GNSBeaconStrategy strategyWithParamsBlock:^(GNSBeaconStrategyParams *params) {
                                    params.includeIBeacons = NO;
                                  };
                            }];

Swift

let beaconSubscription = messageManager.subscriptionWithMessageFoundHandler(
    myMessageFoundHandler, messageLostHandler: myMessageLostHandler,
    paramsBlock: { (params: GNSSubscriptionParams!) in
      params.deviceTypesToDiscover = .BLEBeacon
      params.beaconStrategy =
          GNSBeaconStrategy(paramsBlock: { (params: GNSBeaconStrategyParams!) in
            params.includeIBeacons = false
          })
    })

デフォルトでは、省電力スキャンが有効になっています。そのため、Eddystone ビーコンの検出時にレイテンシが大きくなる場合があります。低電力モードを無効にすると、iBeacon スキャンを使用して Eddystone ビーコンを検出できるため、こうしたレイテンシを削減できます。ただし、この場合はバッテリー使用量が多くなり、iOS はユーザーに位置情報を使用する許可を求めます。

次のスニペットは、Eddystone ビーコンをスキャンするときに低電力モードを無効にする方法を示しています。

Objective-C

id<GNSSubscription> beaconSubscription = [messageManager
    subscriptionWithMessageFoundHandler:myMessageFoundHandler
                     messageLostHandler:myMessageLostHandler
                            paramsBlock:^(GNSSubscriptionParams *params) {
                              params.deviceTypesToDiscover = kGNSDeviceBLEBeacon;
                              params.beaconStrategy =
                                  [GNSBeaconStrategy strategyWithParamsBlock:^(GNSBeaconStrategyParams *params) {
                                    params.includeIBeacons = NO;
                                    params.lowPowerPreferred = NO;
                                  };
                            }];

Swift

let beaconSubscription = messageManager.subscriptionWithMessageFoundHandler(
    myMessageFoundHandler, messageLostHandler: myMessageLostHandler,
    paramsBlock: { (params: GNSSubscriptionParams!) in
      params.deviceTypesToDiscover = .BLEBeacon
      params.beaconStrategy =
          GNSBeaconStrategy(paramsBlock: { (params: GNSBeaconStrategyParams!) in
            params.includeIBeacons = false
            params.lowPowerPreferred = false
          })
    })

iBeacon のスキャンでは、iOS の位置情報の利用許可ダイアログの前にニアバイシェアの権限ダイアログが表示されます。このダイアログをオーバーライドする場合(たとえば、位置情報の利用許可が必要な理由を説明する「プリフライト」ダイアログを提供する場合)、サブスクリプション パラメータで permissionRequestHandler をカスタム ブロックに設定します。次のスニペットは、その方法を示しています。

Objective-C

id<GNSSubscription> beaconSubscription = [messageManager
    subscriptionWithMessageFoundHandler:myMessageFoundHandler
                     messageLostHandler:myMessageLostHandler
                            paramsBlock:^(GNSSubscriptionParams *params) {
                              params.deviceTypesToDiscover = kGNSDeviceBLEBeacon;
                              params.permissionRequestHandler = ^(GNSPermissionHandler permissionHandler) {
                                // Show your custom dialog here, and don't forget to call permissionHandler after it is dismissed
                                permissionHandler(userGavePermission);
                              };
                            }];

Swift

let beaconSubscription = messageManager.subscriptionWithMessageFoundHandler(
    myMessageFoundHandler, messageLostHandler: myMessageLostHandler,
    paramsBlock: { (params: GNSSubscriptionParams!) in
      params.deviceTypesToDiscover = .BLEBeacon
      params.permissionRequestHandler = { (permissionHandler: GNSPermissionHandler!) in
        // Show your custom dialog here, and don't forget to call permissionHandler after it is dismissed
        permissionHandler(userGavePermission);
      }
    })

バックグラウンド スキャン

ビーコン スキャンは BLE を使用するため、バックグラウンドで動作します。バックグラウンド モードを使用する場合は、次の点を考慮してください。

  • バックグラウンド BLE では追加でバッテリーが消費されます。コストは低く抑えられますが、バックグラウンド モードを使用するかどうかを決める前に、コストを測定する必要があります。
  • iOS では、iBeacon スキャンが有効になっているか低電力モードが無効になっている場合、バックグラウンドで位置情報を使用する許可をユーザーに求めます。

バックグラウンドでビーコン スキャンを有効にするには、次の追加手順を行います。

  • 適切に構成された GNSBeaconStrategy オブジェクトを渡すことで、サブスクリプションのバックグラウンド モードを有効にします。次のスニペットは、その方法を示しています。

    Objective-C

    id<GNSSubscription> beaconSubscription = [messageManager
        subscriptionWithMessageFoundHandler:myMessageFoundHandler
                         messageLostHandler:myMessageLostHandler
                                paramsBlock:^(GNSSubscriptionParams *params) {
                                  params.deviceTypesToDiscover = kGNSDeviceBLEBeacon;
                                  params.beaconStrategy = [GNSBeaconStrategy
                                      strategyWithParamsBlock:^(GNSBeaconStrategyParams *params) {
                                        params.allowInBackground = YES;
                                      }];
                                }];
    

    Swift

    let beaconSubscription = messageManager.subscriptionWithMessageFoundHandler(
        myMessageFoundHandler, messageLostHandler: myMessageLostHandler,
        paramsBlock: { (params: GNSSubscriptionParams!) in
          params.deviceTypesToDiscover = .BLEBeacon
          params.beaconStrategy =
              GNSBeaconStrategy(paramsBlock: { (params: GNSBeaconStrategyParams!) in
                params.allowInBackground = true
              })
        })
    

  • 必要なエントリをアプリの Info.plist に追加します。

    • UIBackgroundModes エントリ:

      • bluetooth-central: バックグラウンドで BLE スキャンを行う場合。
      • location: 高電力モードを使用してバックグラウンドで iBeacon スキャンを行います。Eddystone ビーコンのみを対象に低電力スキャンを実行する場合は、このオプションを省略できます。
    • NSLocationAlwaysUsageDescription: バックグラウンドでユーザーの位置情報を追跡する理由を説明する文字列。たとえば、「バックグラウンドでビーコンをスキャンするには位置情報が必要です」などです。詳しくは、Apple のドキュメントをご覧ください。Eddystone ビーコンに対してのみ低電力スキャンを実行する場合は、このオプションを省略できます。

  • ユーザーはアプリのバックグラウンド スキャンを有効または無効にできますか?アプリがバックグラウンドで実行されている間、iOS ではいつでも強制終了できるため、バックグラウンド モードの値を NSUserDefaults に保存する必要があります。アプリは次のことを行う必要があります。

    • ユーザーが変更するたびに、バックグラウンド モードの値を NSUserDefaults に保存します。
    • 起動時に NSUserDefaults から読み取り、バックグラウンド モードが有効になっている場合はビーコン サブスクリプションを復元します。

バックグラウンド通知

バックグラウンドでビーコンを検出したときにアプリがユーザーに通知されるようにするには、ローカル通知を使用します。詳しくは、バックグラウンド通知をご覧ください。