Otrzymywanie obrazów typu beacon

Twoja aplikacja może subskrybować wiadomości z beaconów Bluetooth Low Energy (BLE) wiadomości z beaconów za pomocą tego samego mechanizmu, który jest używany do subskrybowania wiadomości publikowanych przez inne urządzenia w pobliżu.

Domyślnie subskrypcje beaconów działają tylko wtedy, gdy aplikacja jest na pierwszym planie. Gdy aplikacja przechodzi w tle, subskrypcje automatycznie przestają skanować beacony. Więcej informacji o tym, jak włączyć skanowanie w tle, znajdziesz w sekcji Skanowanie w tle.

Aby subskrybować beacony, ustaw parametr deviceTypesToDiscover na kGNSDeviceBLEBeacon w parametrach subskrypcji. Poniższy 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 otrzymuje wszystkie wiadomości z tych beaconów. Jeśli chcesz otrzymywać wiadomości z beaconów zarejestrowanych w innej przestrzeni nazw, możesz przekazać przestrzeń nazw w parametrach subskrypcji. Podobnie, jeśli chcesz otrzymywać wiadomości określonego typu, możesz też przekazać typ wiadomości do filtrowania. Poniższy 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 oba typy beaconów: Eddystone i iBeacon. Gdy skanowanie iBeacon jest włączone, użytkownicy będą proszeni o zgodę na używanie przez aplikację danych o lokalizacji. Plik Info.plist aplikacji musi zawierać klucz NSLocationWhenInUseUsageDescription z krótkim wyjaśnieniem, dlaczego używana jest lokalizacja. Szczegółowe informacje znajdziesz w dokumentacji Apple.

Jeśli chcesz skanować tylko beacony Eddystone, możesz wyłączyć skanowanie iBeacon w GNSBeaconStrategy, a iOS nie będzie prosić użytkownika o zgodę na używanie lokalizacji. Poniższy fragment kodu pokazuje, jak wyłączyć skanowanie iBeacon w przypadku oryginalnej 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 z niskim zużyciem energii, co czasami może powodować duże opóźnienia podczas znajdowania beaconów Eddystone. Gdy tryb oszczędzania baterii jest wyłączony, do znajdowania beaconów Eddystone używane jest skanowanie iBeacon, co może zmniejszyć te opóźnienia. Powoduje to jednak większe wykorzystanie baterii, a iOS poprosi użytkownika o zgodę na używanie lokalizacji.

Poniższy fragment kodu pokazuje, jak wyłączyć tryb oszczędzania baterii podczas skanowania 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 iBeacon okno z prośbą o zgodę na dostęp do lokalizacji w iOS jest poprzedzone oknem z prośbą o zgodę na dostęp do urządzeń w pobliżu. Jeśli chcesz zastąpić to okno dialogowe (np. aby wyświetlić okno „przed lotem”, które wyjaśnia, dlaczego potrzebna jest zgoda na dostęp do lokalizacji), ustaw permissionRequestHandler na niestandardowy blok w parametrach subskrypcji. Poniższy 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

Skanowanie beaconów korzysta z BLE, więc może działać w tle. Oto kilka kwestii, o których należy pamiętać, gdy zdecydujesz się na używanie trybu w tle:

  • Korzystanie z BLE w tle wiąże się z dodatkowym zużyciem baterii. Zużycie jest niewielkie, ale przed podjęciem decyzji o używaniu trybu w tle warto je zmierzyć.
  • Jeśli skanowanie iBeacon jest włączone lub tryb oszczędzania baterii jest wyłączony, iOS poprosi użytkownika o zgodę na używanie lokalizacji w tle.

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

  • Włącz tryb w tle dla subskrypcji, przekazując prawidłowo skonfigurowany obiekt GNSBeaconStrategy. Poniższy 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 pliku Info.plist aplikacji:

    • Wpisy UIBackgroundModes:

      • bluetooth-central do skanowania BLE w tle.
      • location do skanowania iBeacon w tle w trybie wysokiego zużycia energii. Możesz pominąć ten krok, jeśli wykonujesz skanowanie z niskim zużyciem energii tylko w przypadku beaconów Eddystone.
    • Ciąg znaków NSLocationAlwaysUsageDescription opisujący, dlaczego będziesz śledzić lokalizację użytkownika w tle. Na przykład „Twoja lokalizacja jest potrzebna do skanowania beaconów w tle”. Szczegółowe informacje znajdziesz w dokumentacji Apple. Możesz pominąć ten krok, jeśli wykonujesz skanowanie z niskim zużyciem energii tylko w przypadku beaconów Eddystone.

  • Czy użytkownik może włączyć lub wyłączyć skanowanie w tle w Twojej aplikacji? Jeśli tak, zapisz wartość trybu w tle w NSUserDefaults, ponieważ iOS może w dowolnym momencie zamknąć aplikację działającą w tle. Twoja aplikacja powinna wykonać te czynności:

    • Zapisz wartość trybu w tle w NSUserDefaults, gdy użytkownik ją zmieni.
    • Po uruchomieniu odczytaj ją z NSUserDefaults i przywróć subskrypcję beaconów, jeśli tryb w tle jest włączony.

Powiadomienia w tle

Jeśli chcesz, aby aplikacja powiadamiała użytkownika o wykryciu beaconów w tle, możesz używać powiadomień lokalnych. Więcej informacji znajdziesz w sekcji Powiadomienia w tle.