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 Messages をアプリに統合する際に発生する可能性のある問題を追跡するのに役立つ重要な内部イベントがコンソールに出力されます。テクニカルサポートにお問い合わせいただいた場合は、これらのログをご提供いただくようお願いすることがあります。
メッセージ マネージャーを作成する前に有効にする必要があります。 次のコード スニペットは、デバッグ ロギングを有効にする方法を示しています。
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
Nearby に影響するユーザー設定をトラッキングする
ユーザーがマイクの権限を拒否した場合、Bluetooth の権限を拒否した場合、または Bluetooth がオフになっている場合、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
}
})
Nearby の権限ダイアログをオーバーライドする
パブリケーションとサブスクリプションに渡すパラメータによっては、Nearby が機能する前に、iOS がさまざまな権限を要求することがあります。たとえば、デフォルトの戦略では、近超音波オーディオで送信されたデータをリッスンするため、iOS はマイクの使用権限を要求します。このような場合、ニアバイシェアは、ユーザーに権限の付与を求める理由を説明する「事前確認」ダイアログを表示します。
カスタムの「プリフライト」ダイアログを表示する場合は、パブリケーションまたはサブスクリプションのパラメータで 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エントリ:bluetooth-centralバックグラウンドでの BLE スキャン用。検出モードにスキャンが含まれている場合にのみ必要です。デフォルトでは含まれています。bluetooth-peripheralバックグラウンドでの BLE 広告用。検出モードにブロードキャストが含まれている場合にのみ必要です。デフォルトでは含まれています。
NSBluetoothPeripheralUsageDescriptionBLE で広告を配信する理由を説明する 文字列。例: 「匿名トークンは Bluetooth を介して広告され、近くのデバイスを検出します。」 詳しくは、 Apple のドキュメント をご覧ください。
アプリは、バックグラウンドで実行中にシステムによっていつでも強制終了される可能性があります。 バックグラウンド モードがユーザーが有効または無効にできる設定である場合、アプリは次のことを行う必要があります。
- ユーザーが変更するたびに、バックグラウンド モードの値を
NSUserDefaultsに保存します。 - 起動時に、
NSUserDefaultsから読み取り、バックグラウンド モードが有効になっている場合は、Nearby のパブリケーションまたはサブスクリプションを復元します。
- ユーザーが変更するたびに、バックグラウンド モードの値を
バックグラウンド通知
アプリがバックグラウンドでサブスクリプションがメッセージを受信したときにユーザーに通知する場合は、 ローカル通知を使用できます。
アプリに追加する手順は次のとおりです。
起動時にローカル通知に登録します。
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... }