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.plistaplikacji:Wpisy
UIBackgroundModes:bluetooth-centraldo skanowania BLE w tle.locationdo 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
NSLocationAlwaysUsageDescriptionopisują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
NSUserDefaultsi przywróć subskrypcję beaconów, jeśli tryb w tle jest włączony.
- Zapisz wartość trybu w tle w
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.