Получить сообщения маяка

Ваше приложение может подписаться на сообщения маяка Bluetooth Low Energy (BLE), используя тот же механизм, который используется для подписки на сообщения, публикуемые другими близлежащими устройствами.

По умолчанию подписки на маяки работают только тогда, когда ваше приложение находится на переднем плане. Когда ваше приложение переходит в фоновый режим, подписки автоматически прекращают сканирование маяков. Подробную информацию о том, как включить фоновое сканирование, см. в разделе Фоновое сканирование .

Чтобы подписаться на маяки, установите для параметра deviceTypesToDiscover значение kGNSDeviceBLEBeacon в параметрах подписки. Следующий фрагмент демонстрирует, как это сделать:

Цель-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
    })

Вышеуказанная подписка обнаруживает только маяки, принадлежащие вашему проекту, и получает все сообщения от этих маяков. Если вы хотите получать сообщения от маяков, зарегистрированных в другом пространстве имен, вы можете передать пространство имен в параметрах подписки. Аналогично, если вам нужен определенный тип сообщения, вы также можете передать тип сообщения для фильтрации. В следующем фрагменте показано, как это сделать:

Цель-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 для исходной подписки, указанной выше:

Цель-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. Когда режим низкого энергопотребления отключен, сканирование iBeacon используется для поиска маяков Eddystone, что может уменьшить эти задержки. Однако это приводит к увеличению расхода заряда батареи, и iOS запрашивает у пользователя разрешение на использование местоположения.

В следующем фрагменте показано, как отключить режим низкого энергопотребления при сканировании маяков Eddystone.

Цель-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 пользовательский блок в параметрах подписки. В следующем фрагменте показано, как это сделать:

Цель-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 . В следующем фрагменте показано, как это сделать:

    Цель-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 и восстановите подписку на маяк, если включен фоновый режим.

Фоновые уведомления

Если вы хотите, чтобы ваше приложение уведомляло пользователя об обнаружении маяков в фоновом режиме, вы можете использовать локальные уведомления . Подробности см. в разделе фоновые уведомления .