公開と登録

Nearby Messages API は、近くのデバイスが小さなペイロードのデータを交換できるパブリッシュ / サブスクライブ API です。デバイスがメッセージを公開すると、近くのデバイスがそのメッセージを受信できます。良好なパフォーマンスを維持するため、メッセージ サイズはかなり小さくする必要があります。このサービスは、写真や動画などの大きなオブジェクトの交換を目的としたものではありません。

付近のデバイスのセットは、Bluetooth と準超音波(聞こえない)音声による小さなトークンの交換によって決定されます。デバイスが付近のデバイスからトークンを検出すると、そのトークンを Nearby Messages サーバーに送信して検証し、アプリケーションの現在のサブスクリプション セットに配信するメッセージがあるかどうかを確認します。

アプリケーションは、デバイス検出に使用されるメディアのセットと、メディアがトークンのブロードキャストやトークンのスキャンに使用されるかどうかを制御できます。デフォルトでは、ブロードキャストとスキャンはすべてのメディアで行われます。サブセットまたはメディアで検出を行い、ブロードキャストまたはスキャンを行うかどうかを制御するには、パブリケーションとサブスクリプションを作成するときに追加のパラメータを渡す必要があります。

このライブラリは iOS 7 以降で動作し、iOS 8 SDK でビルドされます。

メッセージ マネージャーの作成

このコードは、パブリッシュとサブスクライブを可能にするメッセージ マネージャー オブジェクトを作成します。メッセージ交換は認証されていないため、iOS 用の公開 API キーを指定する必要があります。プロジェクトの Google Developers Console エントリを使用して作成できます。

Objective-C

#import <GNSMessages.h>

GNSMessageManager *messageManager =
    [[GNSMessageManager alloc] initWithAPIKey:@"API_KEY"];

Swift

let messageManager = GNSMessageManager(APIKey: "API_KEY")

メッセージを公開する

このコード スニペットは、名前を含むメッセージをパブリッシュする方法を示しています。パブリケーション オブジェクトが存在する限り、パブリケーションはアクティブです。公開を停止するには、パブリケーション オブジェクトを解放します。

Objective-C

id<GNSPublication> publication =
    [messageManager publicationWithMessage:[GNSMessage messageWithContent:[name dataUsingEncoding:NSUTF8StringEncoding]]];

Swift

let publication =
    messageManager.publication(with: GNSMessage(content: name.data(using: .utf8)))

メッセージのサブスクライブ

このコード スニペットは、前のパブリケーション スニペットで共有されたすべての名前をサブスクライブする方法を示しています。サブスクリプション オブジェクトが存在する限り、サブスクリプションは有効です。登録を停止するには、サブスクリプション オブジェクトを解放します。

メッセージをパブリッシュしている付近のデバイスが検出されると、メッセージ検出ハンドラが呼び出されます。メッセージが観測されなくなった場合(デバイスが範囲外になったか、メッセージの公開を停止した場合)、メッセージ損失ハンドラが呼び出されます。

Objective-C

id<GNSSubscription> subscription =
    [messageManager subscriptionWithMessageFoundHandler:^(GNSMessage *message) {
      // Add the name to a list for display
    }
    messageLostHandler:^(GNSMessage *message) {
      // Remove the name from the list
    }];

Swift

let subscription =
    messageManager.subscription(messageFoundHandler: { (message: GNSMessage?) in
      // Add the name to a list for display
    },
    messageLostHandler: { (message: GNSMessage?) in
      // Remove the name from the list
    })

検出メディア

デフォルトでは、付近のデバイスの検出に音声と Bluetooth の両方が使用され、両方でブロードキャストとスキャンが行われます。特定のケースでは、アプリの Info.plist に次のエントリを追加する必要があります。

  • アプリが音声を使用してスキャンする場合は、マイクを使用する理由を説明する文字列である NSMicrophoneUsageDescription を追加します。たとえば、「マイクは付近のデバイスから匿名トークンをリッスンします。」

  • アプリが BLE を使用してブロードキャストする場合は、BLE で広告を掲載する理由を説明する文字列である NSBluetoothPeripheralUsageDescription を追加します。たとえば、「匿名トークンは、付近のデバイスを検出するために Bluetooth 経由でアドバタイズされます。」

アプリで 1 つのメディアのみを使用する必要がある場合や、そのメディアでブロードキャストとスキャンを両方行う必要がない場合もあります。

たとえば、音声のみをブロードキャストしているセットトップ ボックスに接続するように設計されたアプリは、音声のみをスキャンして検出する必要があります。次のスニペットは、検出に音声スキャンのみを使用して、そのセットトップ ボックスにメッセージをパブリッシュする方法を示しています。

Objective-C

id<GNSPublication> publication = [messageManager publicationWithMessage:message
    paramsBlock:^(GNSPublicationParams *params) {
      params.strategy = [GNSStrategy strategyWithParamsBlock:^(GNSStrategyParams *params) {
        params.discoveryMediums = kGNSDiscoveryMediumsAudio;
        params.discoveryMode = kGNSDiscoveryModeScan;
      }];
    }];

Swift

let publication = messageManager.publication(with: message,
    paramsBlock: { (params: GNSPublicationParams?) in
      guard let params = params else { return }
      params.strategy = GNSStrategy(paramsBlock: { (params: GNSStrategyParams?) in
        guard let params = params else { return }
        params.discoveryMediums = .audio
        params.discoveryMode = .scan
      })
    })

デバッグ ロギングを有効にする

デバッグ ロギングでは、Nearby メッセージをアプリに統合する際に発生する可能性のある問題の追跡に役立つ重要な内部イベントがコンソールに出力されます。テクニカル サポートをご利用の際は、これらのログをご提供いただくようお願いすることがあります。

メッセージ マネージャーを作成する前に有効にする必要があります。次のコード スニペットは、デバッグ ロギングを有効にする方法を示しています。

Objective-C

[GNSMessageManager setDebugLoggingEnabled:YES];

Swift

GNSMessageManager.setDebugLoggingEnabled(true)

Nearby 権限の状態をトラッキングする

デバイス検出を有効にするには、ユーザーの同意が必要です。これは、Nearby 権限の状態によって示されます。パブリケーションまたはサブスクリプションを作成する最初の呼び出しで、ユーザーに同意ダイアログが表示されます。ユーザーが同意しない場合、デバイスの検出は機能しません。この場合、アプリはデバイス検出が無効になっていることをユーザーに知らせるメッセージを表示する必要があります。権限の状態は NSUserDefaults に保存されます。

次のスニペットは、権限の状態をサブスクライブする方法を示しています。権限状態変更ハンドラは、状態が変化するたびに呼び出されます。ユーザーが権限を付与または拒否するまでは、初回は呼び出されません。購読を停止するには、権限オブジェクトを解放します。

Objective-C

GNSPermission *nearbyPermission = [[GNSPermission alloc] initWithChangedHandler:^(BOOL granted) {
  // Update the UI here
}];

Swift

let nearbyPermission = GNSPermission(changedHandler: { (granted: Bool) in
  // Update the UI here
})

アプリでは、ユーザーが権限の状態を変更できる方法を提供できます。たとえば、設定ページの切り替えスイッチを使用するなどです。

権限の状態を取得して設定する方法の例を次に示します。

Objective-C

BOOL permissionState = [GNSPermission isGranted];
[GNSPermission setGranted:!permissionState];  // toggle the state

Swift

let permissionState = GNSPermission.isGranted()
GNSPermission.setGranted(!permissionState)  // toggle the state

ニアバイに影響するユーザー設定の追跡

ユーザーがマイクの権限を拒否している場合、Bluetooth の権限を拒否している場合、または Bluetooth をオフにしている場合、Nearby は正常に動作しないか、まったく動作しない可能性があります。このような場合は、アプリにメッセージを表示して、Nearby の動作が妨げられていることをユーザーに警告する必要があります。次のスニペットは、メッセージ マネージャーの作成時にハンドラを渡すことで、これらのユーザー設定のステータスをトラッキングする方法を示しています。

Objective-C

GNSMessageManager *messageManager = [[GNSMessageManager alloc]
    initWithAPIKey:API_KEY
       paramsBlock:^(GNSMessageManagerParams *params) {
         params.microphonePermissionErrorHandler = ^(BOOL hasError) {
           // Update the UI for microphone permission
         };
         params.bluetoothPowerErrorHandler = ^(BOOL hasError) {
           // Update the UI for Bluetooth power
         };
         params.bluetoothPermissionErrorHandler = ^(BOOL hasError) {
           // Update the UI for Bluetooth permission
         };
}];

Swift

let messageManager = GNSMessageManager(
         APIKey: API_KEY,
    paramsBlock: { (params: GNSMessageManagerParams?) in
      guard let params = params else { return }
      params.microphonePermissionErrorHandler = { (hasError: Bool) in
        // Update the UI for microphone permission
      }
      params.bluetoothPowerErrorHandler = { (hasError: Bool) in
        // Update the UI for Bluetooth power
      }
      params.bluetoothPermissionErrorHandler = { (hasError: Bool) in
        // Update the UI for Bluetooth permission
      }
    })

付近のデバイスの権限ダイアログをオーバーライドする

パブリケーションとサブスクリプションに渡すパラメータに応じて、iOS は Nearby の機能を許可する前にさまざまな権限をリクエストする場合があります。たとえば、デフォルトの戦略では、超音波に近い音声で送信されたデータをリッスンするため、iOS はマイクの使用許可を求めます。このような場合、Nearby では、ユーザーに権限の付与を求める理由を説明する「事前確認」ダイアログが表示されます。

カスタムの「プリフライト」ダイアログを表示する場合は、パブリケーションまたはサブスクリプションのパラメータで permissionRequestHandler パラメータをカスタム ブロックに設定します。カスタム ブロックは、ユーザーが応答した後に permissionHandler ブロックを呼び出す必要があります。次のスニペットは、パブリケーションでこれを行う方法を示しています。

Objective-C

id<GNSPublication> publication =
    [messageManager publicationWithMessage:[GNSMessage messageWithContent:[name dataUsingEncoding:NSUTF8StringEncoding]]
                               paramsBlock:^(GNSPublicationParams *params) {
                                 params.permissionRequestHandler = ^(GNSPermissionHandler permissionHandler) {
                                   // Show your custom dialog here.
                                   // Don't forget to call permissionHandler() with YES or NO when the user dismisses it.
                                 };
                               }];

Swift

let publication =
    messageManager.publication(with: GNSMessage(content: name.data(using: .utf8)),
        paramsBlock: { (params: GNSPublicationParams?) in
          guard let params = params else { return }
          params.permissionRequestHandler = { (permissionHandler: GNSPermissionHandler?) in
            // Show your custom dialog here.
            // Don't forget to call permissionHandler() with true or false when the user dismisses it.
          }
        })

バックグラウンド オペレーション

デバイス検出に BLE を使用するパブリケーションとサブスクリプションは、バックグラウンドで動作できます。バックグラウンド モードの使用を決定する際は、次の点に注意してください。

  • バックグラウンド オペレーションは BLE メディアのみを使用する必要があります。音声はサポートされていません。
  • バックグラウンド BLE にはバッテリーの追加コストがかかります。コストは低いですが、バックグラウンド モードを使用する前に測定する必要があります。
  • iOS は、バックグラウンドで BLE を介して広告を配信する権限をユーザーに求めます。

パブリケーションまたはサブスクリプションにバックグラウンド モードを追加するには、次の追加の手順を行います。

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

    Objective-C

    id<GNSSubscription> subscription =
        [messageManager subscriptionWithMessageFoundHandler:^(GNSMessage *message) {
          // Add the name to a list for display
        }
        messageLostHandler:^(GNSMessage *message) {
          // Remove the name from the list
        }
        paramsBlock:^(GNSSubscriptionParams *params) {
          params.strategy = [GNSStrategy strategyWithParamsBlock:^(GNSStrategyParams *params) {
            params.allowInBackground = YES;
            params.discoveryMediums = kGNSDiscoveryMediumsBLE;
          }];
        }];
    

    Swift

    let subscription =
        messageManager.subscription(messageFoundHandler: { (message: GNSMessage?) in
          // Add the name to a list for display
        },
        messageLostHandler: { (message: GNSMessage?) in
          // Remove the name from the list
        },
        paramsBlock:{ (params: GNSSubscriptionParams?) in
          guard let params = params else { return }
          params.strategy = GNSStrategy(paramsBlock: { (params: GNSStrategyParams?) in
            guard let params = params else { return }
            params.allowInBackground = true
            params.discoveryMediums = .BLE
          })
        })
    

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

    • UIBackgroundModes エントリ:

      • バックグラウンドでの BLE スキャン用の bluetooth-central。検出モードにスキャンが含まれている場合にのみ必要です。デフォルトではスキャンが含まれています。
      • バックグラウンドでの BLE アドバタイズの bluetooth-peripheral。検出モードにブロードキャストが含まれている場合にのみ必要です。デフォルトで含まれています。
    • BLE でアドバタイズする理由を説明する NSBluetoothPeripheralUsageDescription 文字列。たとえば、「匿名トークンは、付近のデバイスを検出するために Bluetooth 経由でアドバタイズされます。」などです。詳しくは、Apple のドキュメントをご覧ください。

  • アプリはバックグラウンドで実行中に、システムによっていつでも強制終了される可能性があります。バックグラウンド モードがユーザーが有効または無効にできる設定である場合、アプリは次の処理を行う必要があります。

    • ユーザーがバックグラウンド モードの値を変更するたびに、その値を NSUserDefaults に保存します。
    • 起動時に NSUserDefaults から読み取り、バックグラウンド モードが有効になっている場合は、付近の公開情報や定期購入を復元します。

バックグラウンド通知

アプリがバックグラウンドにあるときに定期購入でメッセージを受信した場合にユーザーに通知するには、ローカル通知を使用します。

アプリに追加する手順は次のとおりです。

  • 起動時にローカル通知を登録します。

    Objective-C

    if ([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)]) {
      [[UIApplication sharedApplication] registerUserNotificationSettings:
          [UIUserNotificationSettings settingsForTypes:
              UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound
                                            categories:nil]];
    }
    

    Swift

    UIApplication.shared.registerUserNotificationSettings(
        UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil))
    

  • サブスクリプションのメッセージ検出ハンドラでローカル通知を送信します。

    Objective-C

    GNSMessageHandler myMessageFoundHandler = ^(GNSMessage *message) {
        // Send a local notification if not in the foreground.
        if ([UIApplication sharedApplication].applicationState != UIApplicationStateActive) {
          UILocalNotification *localNotification = [[UILocalNotification alloc] init];
          localNotification.alertBody = @"Message received";
          [[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
        }
        // Process the new message...
      };
    

    Swift

    let myMessageFoundHandler: GNSMessageHandler = { (message: GNSMessage?) in
      // Send a local notification if not in the foreground.
      if UIApplication.shared.applicationState != .active {
        let localNotification = UILocalNotification()
        localNotification.alertBody = "Message received"
        UIApplication.shared.presentLocalNotificationNow(localNotification)
      }
      // Process the new message...
    }