您的应用可以使用与订阅附近其他设备发布的消息相同的机制来订阅低功耗蓝牙 (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
})
上述订阅仅发现您的项目拥有的信标,并接收来自这些信标的所有消息。如果您想接收来自使用其他命名空间注册的信标的消息,可以在订阅参数中传递命名空间。同样,如果您需要特定类型的消息,也可以传递消息类型进行过滤。以下代码段展示了如何执行此操作:
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个条目:bluetooth-central,用于在后台进行 BLE 扫描。location,用于在后台使用高功率模式扫描 iBeacon。 如果您仅对 Eddystone 信标执行低功耗扫描,则可以省略此步骤。
NSLocationAlwaysUsageDescription字符串,用于说明您为何要在后台跟踪用户的位置信息。例如,“需要您的位置信息才能在后台扫描信标。”如需了解详情,请参阅 Apple 的文档。如果您仅对 Eddystone 信标进行低功耗扫描,则可以省略此步骤。
用户能否在您的应用中启用或停用后台扫描?如果是,您应将后台模式值保存到
NSUserDefaults,因为 iOS 可能会在应用处于后台时随时终止应用。您的应用应执行以下操作:- 每当用户更改后台模式值时,都将其保存到
NSUserDefaults。 - 在启动时,从
NSUserDefaults中读取该信息,并在后台模式处于启用状态时恢复信标订阅。
- 每当用户更改后台模式值时,都将其保存到