Otrzymywanie obrazów typu beacon

Aplikacja może subskrybować wiadomości z beaconów Bluetooth Low Energy (BLE) 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 sygnałów beacon działają tylko wtedy, gdy aplikacja jest na pierwszym planie. Gdy aplikacja przechodzi w tło, subskrypcje automatycznie przestają skanować sygnały beacon. Więcej informacji o włączaniu skanowania w tle znajdziesz w sekcji Skanowanie w tle.

Aby zasubskrybować sygnały, 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 otrzymać określony typ wiadomości, 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 zezwolenie aplikacji na korzystanie z danych o lokalizacji. Info.plist aplikacji musi zawierać klucz NSLocationWhenInUseUsageDescription z krótkim wyjaśnieniem, dlaczego używana jest lokalizacja. Szczegóły znajdziesz w dokumentacji Apple.

Jeśli chcesz skanować tylko w poszukiwaniu beaconów Eddystone, możesz wyłączyć skanowanie iBeaconów w GNSBeaconStrategy, a iOS nie będzie prosić użytkownika o zgodę na korzystanie z lokalizacji. Poniższy fragment kodu pokazuje, jak wyłączyć skanowanie iBeacon w przypadku 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 z niskim poborem mocy, co czasami może powodować duże opóźnienia podczas wyszukiwania beaconów Eddystone. Gdy tryb niskiego zużycia energii jest wyłączony, skanowanie iBeacon jest używane do wyszukiwania beaconów Eddystone, co może skrócić te opóźnienia. Powoduje to jednak większe zużycie baterii, a system iOS poprosi użytkownika o zezwolenie na korzystanie z lokalizacji.

Poniższy fragment kodu pokazuje, jak wyłączyć tryb niskiego zużycia energii 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ów przed oknem z prośbą o przyznanie uprawnień do lokalizacji w iOS wyświetla się okno z prośbą o przyznanie uprawnień do urządzeń w pobliżu. Jeśli chcesz zastąpić to okno (np. wyświetlić okno „przed lotem”, które wyjaśnia, dlaczego potrzebne jest uprawnienie do lokalizacji), ustaw parametr 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 wykorzystuje technologię BLE, więc może działać w tle. Oto kilka kwestii, o których musisz pamiętać, gdy zdecydujesz się używać trybu tła:

  • W przypadku BLE w tle występuje dodatkowy koszt baterii. Koszt jest niski, ale przed podjęciem decyzji o użyciu trybu działania w tle warto go zmierzyć.
  • iOS poprosi użytkownika o zgodę na korzystanie z lokalizacji w tle, jeśli skanowanie iBeacon jest włączone lub tryb niskiego zużycia energii jest wyłączony.

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

  • Włącz tryb tła 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:

    • UIBackgroundModes wpisy:

      • bluetooth-central do skanowania BLE w tle.
      • location do skanowania iBeacon w tle w trybie wysokiej mocy. Możesz pominąć ten krok, jeśli skanujesz tylko sygnały Eddystone w trybie niskiego zużycia energii.
    • NSLocationAlwaysUsageDescription ciąg znaków 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óły znajdziesz w dokumentacji Apple. Możesz pominąć ten krok, jeśli wykonujesz skanowanie w trybie niskiego zużycia 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 jest, zapisz wartość trybu tła w NSUserDefaults, ponieważ iOS może w każdej chwili zamknąć aplikację działającą w tle. Aplikacja powinna:

    • Zapisuj wartość trybu działania w tle w NSUserDefaults za każdym razem, gdy użytkownik ją zmieni.
    • Podczas uruchamiania odczytaj go z NSUserDefaults i przywróć subskrypcję sygnału, jeśli włączony jest tryb działania w tle.

Powiadomienia w tle

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