Otrzymywanie obrazów typu beacon

Aplikacja może subskrybować wiadomości beacon Bluetooth Low Energy (BLE) za pomocą tego samego mechanizmu co w przypadku subskrypcji wiadomości publikowanych przez inne urządzenia w pobliżu.

Domyślnie subskrypcje obrazów typu beacon działają tylko wtedy, gdy aplikacja działa na pierwszym planie. Gdy aplikacja pracuje w tle, subskrypcje automatycznie przestaną szukać beaconów. Więcej informacji o włączaniu skanowania w tle znajdziesz w sekcji Skanowanie w tle.

Aby subskrybować beacony, ustaw parametr deviceTypesToDiscover na kGNSDeviceBLEBeacon w parametrach subskrypcji. Ten fragment kodu pokazuje, jak to zrobić:

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
    })

Powyższa subskrypcja wykrywa tylko beacony należące do Twojego projektu i odbiera z nich wszystkie wiadomości. Jeśli chcesz otrzymywać wiadomości z beaconów zarejestrowanych w innej przestrzeni nazw, możesz przekazać przestrzeń nazw w parametrach subskrypcji. Jeśli potrzebujesz wiadomości określonego typu, możesz też przekazać ich typ do filtrowania. Ten fragment kodu pokazuje, jak to zrobić:

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"
    })

Domyślnie subskrypcja beaconów skanuje obydwa rodzaje beaconów – Eddystone i iBeacon. Gdy skanowanie iBeacon jest włączone, użytkownicy są proszeni o udzielenie uprawnień aplikacji do korzystania z danych o lokalizacji. Info.plist Twojej aplikacji musi zawierać klucz NSLocationWhenInUseUsageDescription z krótkim wyjaśnieniem, dlaczego używasz lokalizacji. Szczegółowe informacje znajdziesz w dokumentacji Apple.

Jeśli chcesz skanować tylko w poszukiwaniu beaconów Eddystone, możesz wyłączyć skanowanie iBeacon w GNSBeaconStrategy, a iOS nie będzie prosić użytkownika o zgodę na korzystanie z lokalizacji. Ten fragment kodu pokazuje, jak wyłączyć skanowanie iBeacon dla pierwotnej subskrypcji powyżej:

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
          })
    })

Domyślnie włączone jest skanowanie o małej mocy, co może czasami powodować duże opóźnienia przy wykrywaniu beaconów Eddystone. Gdy tryb niskiego zużycia energii jest wyłączony, skanowanie iBeacon pomaga znaleźć beacony Eddystone, co może zmniejszyć te opóźnienia. Spowoduje to jednak większe wykorzystanie baterii, a iOS poprosi użytkownika o pozwolenie na korzystanie z lokalizacji.

Poniższy fragment kodu pokazuje, jak wyłączyć tryb oszczędzania energii podczas skanowania w poszukiwaniu beaconów 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
          })
    })

Podczas skanowania w poszukiwaniu iBeacons okno dostępu do lokalizacji w iOS poprzedza okno uprawnień dla funkcji W pobliżu. Jeśli chcesz zastąpić to okno (na przykład aby udostępnić okno procesu wstępnego wyjaśniające, dlaczego potrzebny jest dostęp do lokalizacji), ustaw permissionRequestHandler na niestandardowy blok w parametrach subskrypcji. Ten fragment kodu pokazuje, jak to zrobić:

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);
      }
    })

Skanowanie w tle

Ponieważ skanowanie beaconów wykorzystuje BLE, może działać w tle. Oto kilka kwestii, o których musisz pamiętać, jeśli chcesz korzystać z trybu w tle:

  • Korzystanie z BLE w tle wiąże się z dodatkowym kosztem baterii. Koszt jest niski, ale należy go zmierzyć, zanim zdecydujemy się na użycie trybu w tle.
  • Jeśli skanowanie iBeacon jest włączone lub wyłączony jest tryb oszczędzania energii, iOS poprosi użytkownika o pozwolenie na korzystanie z lokalizacji w tle.

Aby włączyć skanowanie beaconów w tle, wykonaj te dodatkowe czynności:

  • Włącz dla subskrypcji tryb działania w tle, przekazując prawidłowo skonfigurowany obiekt GNSBeaconStrategy. Ten fragment kodu pokazuje, jak to zrobić:

    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
              })
        })
    

  • Dodaj wymagane wpisy do folderu Info.plist Twojej aplikacji:

    • UIBackgroundModes wpisy:

      • bluetooth-central, aby skanować BLE w tle.
      • location, aby skanować w tle iBeacon z wykorzystaniem trybu wysokiego zużycia energii. Możesz pominąć ten krok, jeśli przeprowadzasz skanowanie tylko pod kątem beaconów Eddystone z małą mocą.
    • Ciąg tekstowy NSLocationAlwaysUsageDescription opisujący, dlaczego będziesz śledzić lokalizację użytkownika w tle. np. „Twoja lokalizacja musi skanować, by w tle nie czuć beaconów”. Szczegółowe informacje znajdziesz w dokumentacji Apple. Możesz pominąć ten krok, jeśli skanujesz jedynie beacony Eddystone z małą mocą.

  • Czy użytkownik może włączyć lub wyłączyć skanowanie w tle w Twojej aplikacji? Jeśli tak, zapisz wartość trybu tła w elemencie NSUserDefaults, ponieważ iOS może zamknąć Twoją aplikację w każdej chwili, gdy działa w tle. Twoja aplikacja powinna spełniać te warunki:

    • Zapisz wartość trybu tła w polu NSUserDefaults za każdym razem, gdy użytkownik ją zmieni.
    • Po uruchomieniu przeczytaj ją w NSUserDefaults i przywróć subskrypcję beacon, jeśli włączony jest tryb w tle.

Powiadomienia w tle

Jeśli chcesz, aby aplikacja powiadamiała użytkownika o wykryciu beaconów, gdy działa w tle, możesz użyć powiadomień lokalnych. Więcej informacji znajdziesz w artykule o powiadomieniach w tle.