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.
- Zapisuj wartość trybu działania w tle w
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.