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.
- Zapisz wartość trybu tła w polu
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.