Nearby Messages API 是一种发布-订阅 API,可让附近的设备 交换小负载的数据。设备发布消息后,就在附近 设备可以接收消息。邮件大小应尽可能小 保持良好性能此服务不支持换取更多 对象(例如照片和视频)。
附近的设备集取决于 蓝牙和近超声(听不到)音频。设备检测到令牌时 它就会将令牌发送到 Nearby Messages 服务器, 验证消息,并检查是否有消息需要传递至应用的 当前订阅的一组新订阅。
应用可以控制用于设备发现的媒介集,以及 媒介是否用于广播令牌和/或扫描令牌。 默认情况下,广播和扫描在所有媒介上都完成。待办事项 或媒介上的发现,以及控制是广播还是扫描, 您必须在创建发布内容时传递额外的参数, 订阅。
此库在 iOS 7 及更高版本上运行,并使用 iOS 8 SDK 构建。
创建消息管理器
此代码会创建一个消息管理器对象,让您可以发布和 订阅。邮件交换未通过身份验证,因此您必须提供一个 公共 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
})
发现媒介
默认情况下,系统会使用这两种媒介(音频和蓝牙)来发现附近的设备
这两种媒介都会进行广播和扫描在某些情况下
将以下条目添加到应用的 Info.plist
中:
如果您的应用使用音频进行扫描,请添加
NSMicrophoneUsageDescription
, 说明您将使用麦克风的原因的字符串。例如,“ 麦克风会监听来自附近设备的匿名令牌。”如果您的应用使用 BLE 进行广播,请将
NSBluetoothPeripheralUsageDescription
,这是一个字符串,用于说明您为何 将在 BLE 上进行广播。例如,“匿名令牌的 来发现附近的设备。”
在某些情况下,您的应用可能只需要使用其中一种媒介 可能不需要在该介质上同时进行广播和扫描。
例如,一款旨在连接到 音频广播只需扫描音频即可发现。以下 展示了如何只使用音频向该机顶盒发布消息 扫描发现:
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
})
})
启用调试日志记录
调试日志记录会将重要的内部事件打印到控制台, 有助于您跟踪在集成“附近”功能时可能遇到的问题 消息发送到您的应用。如果您与我们联系,我们将要求您提供这些日志 获取技术支持。
您应在创建消息管理器之前启用它。此代码段显示了 如何启用调试日志记录:
Objective-C
[GNSMessageManager setDebugLoggingEnabled:YES];
Swift
GNSMessageManager.setDebugLoggingEnabled(true)
跟踪 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
跟踪会影响“附近”功能的用户设置
如果用户已拒绝授予麦克风权限、拒绝了蓝牙权限或 已关闭蓝牙,“附近”功能将无法正常运行,或可能根本无法运行。 在这些情况下,您的应用应显示一条消息,提醒用户附近 运营受到限制。以下代码段展示了如何跟踪 用户设置的状态,即在创建消息时传递处理程序 经理:
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 可能会请求各种权限。对于 默认策略会监听在近超声波材料上传输的数据 音频,因此 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 进行通告的权限。
如需为发布内容或订阅添加后台模式,请按照这些额外 步骤:
若想在您的发布内容或订阅中启用后台模式和仅限 BLE,请通过以下方式 传入正确配置的
GNSStrategy
对象。以下代码段 展示了如何对订阅执行此操作: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 广播。所需 仅当发现模式包括广播时;默认情况。
NSBluetoothPeripheralUsageDescription
字符串,用于说明原因 您将通过 BLE 进行广告宣传。例如,“匿名令牌是 通过蓝牙通告来发现附近的设备。”请参阅 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... }