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

アプリは、近くにある他のデバイスから公開されたメッセージを登録するのと同じメカニズムを使用して、Bluetooth Low Energy(BLE)ビーコン メッセージを登録できます。

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

ビーコンをサブスクライブするには、サブスクリプション パラメータで 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
    })

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

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 にはバッテリーの追加コストがかかります。コストは低いですが、バックグラウンド モードを使用する前に測定する必要があります。
  • iBeacon スキャンが有効になっているか、低電力モードが無効になっている場合、iOS はバックグラウンドで位置情報を使用する権限をユーザーに求めます。

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

  • 適切に構成された 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 エントリ:

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

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

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

バックグラウンド通知

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