Ваше приложение может подписываться на сообщения маяка Bluetooth Low Energy (BLE), используя тот же механизм, который используется для подписки на сообщения, публикуемые другими близлежащими устройствами.
По умолчанию подписки на маяки работают только тогда, когда приложение находится на переднем плане. Когда приложение переходит в фоновый режим, подписки автоматически прекращают сканирование на наличие маяков. Подробнее о включении фонового сканирования см. в разделе «Фоновое сканирование».
Чтобы подписаться на маяки, установите для параметра deviceTypesToDiscover
значение kGNSDeviceBLEBeacon
в параметрах подписки. Следующий фрагмент кода демонстрирует, как это сделать:
Objective-C
id<GNSSubscription> beaconSubscription = [messageManager
subscriptionWithMessageFoundHandler:myMessageFoundHandler
messageLostHandler:myMessageLostHandler
paramsBlock:^(GNSSubscriptionParams *params) {
params.deviceTypesToDiscover = kGNSDeviceBLEBeacon;
}];
Быстрый
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";
}];
Быстрый
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, вы можете отключить сканирование iBeacon в GNSBeaconStrategy
, и 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;
};
}];
Быстрый
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. При отключении режима низкого энергопотребления для поиска маяков Eddystone используется сканирование iBeacon, что может сократить эти задержки. Однако это приводит к повышенному расходу заряда батареи, и 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;
};
}];
Быстрый
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
})
})
При сканировании маяков iBeacons диалоговому окну разрешения на доступ к данным о местоположении 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);
};
}];
Быстрый
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 влечет за собой дополнительную нагрузку на аккумулятор. Стоимость невелика, но перед использованием фонового режима следует оценить её.
- iOS запросит у пользователя разрешение на использование местоположения в фоновом режиме, если включено сканирование iBeacon или отключен режим низкого энергопотребления.
Чтобы включить сканирование маяков в фоновом режиме, выполните следующие дополнительные действия:
Включите фоновый режим для вашей подписки, передав правильно настроенный объект
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; }]; }];
Быстрый
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
и восстановите подписку на маяк, если включен фоновый режим.
- Сохраняйте значение фонового режима в
Фоновые уведомления
Если вы хотите, чтобы ваше приложение уведомляло пользователя об обнаружении маяков в фоновом режиме, вы можете использовать локальные уведомления . Подробнее см. в разделе «Фоновые уведомления» .