Interfejs w pobliżu do obsługi wiadomości to interfejs API publikowania i subskrypcji, który umożliwia urządzeniom w pobliżu wymianę niewielkich ładunków danych. Gdy urządzenie opublikuje wiadomość, urządzenia w pobliżu mogą ją odebrać. Aby zachować dobrą wydajność, rozmiar wiadomości powinien być dość mały. Ta usługa nie służy do wymiany większych obiektów, takich jak zdjęcia czy filmy.
Zestaw urządzeń w pobliżu określa się na podstawie wymiany niewielkich tokenów przez Bluetooth i dźwięk bliski ultradźwiękowych (niesłyszalnych) dźwięków. Gdy urządzenie wykryje token z urządzenia w pobliżu, wysyła go do serwera Wiadomości w pobliżu, aby go zweryfikować i sprawdzić, czy są dostępne jakieś wiadomości do dostarczenia dla bieżącego zestawu subskrypcji aplikacji.
Aplikacja może kontrolować zbiór nośników używanych do wykrywania urządzeń oraz to, czy mają one być używane do wysyłania tokenów lub skanowania w poszukiwaniu tokenów. Domyślnie transmisja i skanowanie odbywa się w przypadku wszystkich mediów. Aby przeprowadzać wykrywanie na podzbiorze lub mediach i określać, czy mają być rozpowszechniane czy skanowane, musisz przekazać dodatkowe parametry podczas tworzenia publikacji i subskrypcji.
Ta biblioteka działa na urządzeniach z iOS 7 i nowszymi wersjami, korzystając z pakietu SDK do iOS 8.
Tworzenie menedżera wiadomości
Ten kod tworzy obiekt menedżera wiadomości, który umożliwia publikowanie i subskrybowanie. Wymiana wiadomości jest nieuwierzytelniona, dlatego musisz podać publiczny klucz interfejsu API dla iOS. Możesz je utworzyć, korzystając z wpisu w Google Developers Console.
Objective-C
#import <GNSMessages.h>
GNSMessageManager *messageManager =
[[GNSMessageManager alloc] initWithAPIKey:@"API_KEY"];
Swift
let messageManager = GNSMessageManager(APIKey: "API_KEY")
Publikowanie wiadomości
Ten fragment kodu pokazuje publikowanie wiadomości zawierającej imię i nazwisko. Publikacja jest aktywna, dopóki istnieje obiekt publikacji. Aby zakończyć publikowanie, zwolnij obiekt publikacji.
Objective-C
id<GNSPublication> publication =
[messageManager publicationWithMessage:[GNSMessage messageWithContent:[name dataUsingEncoding:NSUTF8StringEncoding]]];
Swift
let publication =
messageManager.publication(with: GNSMessage(content: name.data(using: .utf8)))
Subskrybowanie wiadomości
Ten fragment kodu ilustruje subskrybowanie wszystkich nazw występujących we fragmencie kodu poprzedniej publikacji. Subskrypcja jest aktywna, dopóki istnieją obiekty subskrypcji. Aby zakończyć subskrybowanie, zwolnij obiekt subskrypcji.
Moduł obsługi znalezionych wiadomości jest wywoływany po wykryciu urządzeń w pobliżu, które publikują wiadomości. Moduł obsługi utraconej wiadomości jest wywoływany, gdy wiadomość nie jest już obserwowana (urządzenie jest poza zasięgiem lub nie jest już publikowane).
Objective-C
id<GNSSubscription> subscription =
[messageManager subscriptionWithMessageFoundHandler:^(GNSMessage *message) {
// Add the name to a list for display
}
messageLostHandler:^(GNSMessage *message) {
// Remove the name from the list
}];
Swift
let subscription =
messageManager.subscription(messageFoundHandler: { (message: GNSMessage?) in
// Add the name to a list for display
},
messageLostHandler: { (message: GNSMessage?) in
// Remove the name from the list
})
Techniki odkrywania
Domyślnie do wykrywania urządzeń w pobliżu używane są oba medium (audio i Bluetooth) – oba rodzaje mediów mogą przesyłać i skanować. W niektórych przypadkach do atrybutu Info.plist
aplikacji musisz dodać te wpisy:
Jeśli aplikacja skanuje treści pod kątem dźwięku, dodaj ciąg znaków
NSMicrophoneUsageDescription
, który opisuje powód użycia mikrofonu. np. „Mikrofon nasłuchuje anonimowych tokenów z urządzeń w pobliżu”.Jeśli Twoja aplikacja do transmisji używa BLE, dodaj ciąg
NSBluetoothPeripheralUsageDescription
, który wyjaśnia, dlaczego chcesz reklamować się w tej technologii. np. „Anonimowy token jest rozgłaszany przez Bluetooth do wykrywania urządzeń w pobliżu”.
W niektórych przypadkach aplikacja może wymagać użycia tylko jednego medium i nie musi jednocześnie udostępniać ani skanować medium.
Na przykład aplikacja, która łączy się z dekoderem, który transmituje dźwięk, musi tylko przeskanować dźwięk, aby go wykryć. Ten fragment kodu pokazuje, jak opublikować wiadomość na dekoderze, korzystając tylko ze skanowania dźwięku.
Objective-C
id<GNSPublication> publication = [messageManager publicationWithMessage:message
paramsBlock:^(GNSPublicationParams *params) {
params.strategy = [GNSStrategy strategyWithParamsBlock:^(GNSStrategyParams *params) {
params.discoveryMediums = kGNSDiscoveryMediumsAudio;
params.discoveryMode = kGNSDiscoveryModeScan;
}];
}];
Swift
let publication = messageManager.publication(with: message,
paramsBlock: { (params: GNSPublicationParams?) in
guard let params = params else { return }
params.strategy = GNSStrategy(paramsBlock: { (params: GNSStrategyParams?) in
guard let params = params else { return }
params.discoveryMediums = .audio
params.discoveryMode = .scan
})
})
Włączanie logowania debugowania
Logowanie debugowania wyświetla w konsoli ważne zdarzenia wewnętrzne, które mogą być pomocne przy śledzeniu problemów napotkanych przy integrowaniu Wiadomości w pobliżu z aplikacją. Będziemy prosić o ich przesłanie, jeśli skontaktujesz się z nami w sprawie pomocy technicznej.
Należy to zrobić, zanim utworzysz menedżera wiadomości. Ten fragment kodu pokazuje, jak włączyć logowanie debugowania:
Objective-C
[GNSMessageManager setDebugLoggingEnabled:YES];
Swift
GNSMessageManager.setDebugLoggingEnabled(true)
Śledzenie stanu uprawnień dostępu do funkcji W pobliżu
Do włączenia wykrywania urządzeń wymagana jest zgoda użytkownika. Jest to sygnalizowane przez stan uprawnień w pobliżu. Przy pierwszym wywołaniu tworzenia publikacji lub subskrypcji użytkownik zobaczy okno z prośbą o zgodę na przetwarzanie danych osobowych. Jeśli użytkownik nie wyrazi zgody, wykrywanie urządzeń nie zadziała. W takim przypadku aplikacja powinna wyświetlać użytkownikom przypomnienie, że wykrywanie urządzeń jest wyłączone. Stan uprawnień jest przechowywany w folderze NSUserDefaults
.
Ten fragment kodu ilustruje subskrybowanie stanu uprawnień. Moduł obsługi zmiany stanu uprawnień jest wywoływany przy każdej zmianie stanu. Nie jest wywoływany za pierwszym razem, dopóki użytkownik nie udzieli lub odmówi zgody. Aby zatrzymać subskrypcję, zwolnij obiekt uprawnień.
Objective-C
GNSPermission *nearbyPermission = [[GNSPermission alloc] initWithChangedHandler:^(BOOL granted) {
// Update the UI here
}];
Swift
let nearbyPermission = GNSPermission(changedHandler: { (granted: Bool) in
// Update the UI here
})
Aplikacja może umożliwiać użytkownikowi zmianę stanu uprawnień, np. za pomocą przełącznika na stronie ustawień.
Oto przykład uzyskiwania i ustawiania stanu uprawnień.
Objective-C
BOOL permissionState = [GNSPermission isGranted];
[GNSPermission setGranted:!permissionState]; // toggle the state
Swift
let permissionState = GNSPermission.isGranted()
GNSPermission.setGranted(!permissionState) // toggle the state
Śledzenie ustawień użytkowników, które mają wpływ na funkcję W pobliżu
Jeśli użytkownik odmówił korzystania z mikrofonu, odmówił korzystania z Bluetootha lub wyłączył Bluetooth, funkcja W pobliżu nie będzie działać prawidłowo lub może w ogóle nie działać. W takich przypadkach aplikacja powinna wyświetlić komunikat informujący użytkownika, że działanie funkcji W pobliżu jest utrudnione. Ten fragment kodu pokazuje, jak śledzić stan tych ustawień użytkownika, przekazując moduły obsługi podczas tworzenia menedżera wiadomości:
Objective-C
GNSMessageManager *messageManager = [[GNSMessageManager alloc]
initWithAPIKey:API_KEY
paramsBlock:^(GNSMessageManagerParams *params) {
params.microphonePermissionErrorHandler = ^(BOOL hasError) {
// Update the UI for microphone permission
};
params.bluetoothPowerErrorHandler = ^(BOOL hasError) {
// Update the UI for Bluetooth power
};
params.bluetoothPermissionErrorHandler = ^(BOOL hasError) {
// Update the UI for Bluetooth permission
};
}];
Swift
let messageManager = GNSMessageManager(
APIKey: API_KEY,
paramsBlock: { (params: GNSMessageManagerParams?) in
guard let params = params else { return }
params.microphonePermissionErrorHandler = { (hasError: Bool) in
// Update the UI for microphone permission
}
params.bluetoothPowerErrorHandler = { (hasError: Bool) in
// Update the UI for Bluetooth power
}
params.bluetoothPermissionErrorHandler = { (hasError: Bool) in
// Update the UI for Bluetooth permission
}
})
Zastępowanie okna uprawnień do korzystania z funkcji W pobliżu
W zależności od parametrów, które przekazujesz do swoich publikacji i subskrypcji, iOS może prosić o różne uprawnienia przed włączeniem funkcji W pobliżu. Na przykład domyślna strategia nasłuchuje danych przesyłanych w dźwiękach bliskich ultradźwięków, dlatego iOS poprosi o pozwolenie na użycie mikrofonu. W takich przypadkach funkcja W pobliżu wyświetli okno procesu wstępnego wyjaśniające, dlaczego użytkownik jest proszony o przyznanie uprawnień.
Jeśli chcesz udostępnić niestandardowe okno procesu wstępnego, ustaw parametr permissionRequestHandler
na niestandardowy blok w parametrach publikacji lub subskrypcji. Blokada niestandardowa musi wywołać blok permissionHandler
po odpowiedzi użytkownika. Ten fragment kodu pokazuje, jak to zrobić w przypadku publikacji:
Objective-C
id<GNSPublication> publication =
[messageManager publicationWithMessage:[GNSMessage messageWithContent:[name dataUsingEncoding:NSUTF8StringEncoding]]
paramsBlock:^(GNSPublicationParams *params) {
params.permissionRequestHandler = ^(GNSPermissionHandler permissionHandler) {
// Show your custom dialog here.
// Don't forget to call permissionHandler() with YES or NO when the user dismisses it.
};
}];
Swift
let publication =
messageManager.publication(with: GNSMessage(content: name.data(using: .utf8)),
paramsBlock: { (params: GNSPublicationParams?) in
guard let params = params else { return }
params.permissionRequestHandler = { (permissionHandler: GNSPermissionHandler?) in
// Show your custom dialog here.
// Don't forget to call permissionHandler() with true or false when the user dismisses it.
}
})
Działanie w tle
Publikacje i subskrypcje korzystające z BLE do wykrywania urządzeń mogą działać w tle. Oto kilka kwestii, o których musisz pamiętać, jeśli chcesz korzystać z trybu w tle:
- Operacje w tle mogą korzystać tylko z medium BLE. Dźwięk nie jest obsługiwany.
- 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.
- iOS poprosi użytkownika o pozwolenie na reklamowanie przez BLE w tle.
Aby dodać tryb działania w tle do publikacji lub subskrypcji, wykonaj te dodatkowe czynności:
Włącz w swojej publikacji lub subskrypcji tryb w tle i tylko BLE, przekazując prawidłowo skonfigurowany obiekt
GNSStrategy
. Ten fragment kodu pokazuje, jak to zrobić w przypadku subskrypcji:Objective-C
id<GNSSubscription> subscription = [messageManager subscriptionWithMessageFoundHandler:^(GNSMessage *message) { // Add the name to a list for display } messageLostHandler:^(GNSMessage *message) { // Remove the name from the list } paramsBlock:^(GNSSubscriptionParams *params) { params.strategy = [GNSStrategy strategyWithParamsBlock:^(GNSStrategyParams *params) { params.allowInBackground = YES; params.discoveryMediums = kGNSDiscoveryMediumsBLE; }]; }];
Swift
let subscription = messageManager.subscription(messageFoundHandler: { (message: GNSMessage?) in // Add the name to a list for display }, messageLostHandler: { (message: GNSMessage?) in // Remove the name from the list }, paramsBlock:{ (params: GNSSubscriptionParams?) in guard let params = params else { return } params.strategy = GNSStrategy(paramsBlock: { (params: GNSStrategyParams?) in guard let params = params else { return } params.allowInBackground = true params.discoveryMediums = .BLE }) })
Dodaj te wpisy do folderu
Info.plist
aplikacji:UIBackgroundModes
wpisy:bluetooth-central
, aby skanować BLE w tle. Wymagany tylko wtedy, gdy tryb wykrywania obejmuje skanowanie. Jest on używany domyślnie.bluetooth-peripheral
, aby wyświetlać reklamy BLE w tle. Wymagany tylko wtedy, gdy tryb wykrywania obejmuje transmisję (domyślnie).
Ciąg tekstowy
NSBluetoothPeripheralUsageDescription
opisujący, dlaczego chcesz reklamować się w BLE. Na przykład: „Do wykrywania urządzeń w pobliżu są rozpowszechniany anonimowy token”. Szczegółowe informacje znajdziesz w dokumentacji Apple.
Aplikacja może zostać zamknięta przez system w dowolnym momencie, gdy działa w tle. Jeśli tryb w tle to ustawienie, które użytkownik może włączyć lub wyłączyć, aplikacja powinna:
- 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óć publikacje lub subskrypcje funkcji W pobliżu, 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 otrzymaniu wiadomości przez subskrypcję w tle, możesz użyć powiadomień lokalnych.
Aby dodać je do aplikacji, wykonaj te czynności:
Rejestrowanie powiadomień lokalnych przy uruchamianiu:
Objective-C
if ([UIApplication instancesRespondToSelector:@selector(registerUserNotificationSettings:)]) { [[UIApplication sharedApplication] registerUserNotificationSettings: [UIUserNotificationSettings settingsForTypes: UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil]]; }
Swift
UIApplication.shared.registerUserNotificationSettings( UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil))
Wyślij powiadomienie lokalne w module obsługi wiadomości znalezionych w subskrypcji:
Objective-C
GNSMessageHandler myMessageFoundHandler = ^(GNSMessage *message) { // Send a local notification if not in the foreground. if ([UIApplication sharedApplication].applicationState != UIApplicationStateActive) { UILocalNotification *localNotification = [[UILocalNotification alloc] init]; localNotification.alertBody = @"Message received"; [[UIApplication sharedApplication] presentLocalNotificationNow:localNotification]; } // Process the new message... };
Swift
let myMessageFoundHandler: GNSMessageHandler = { (message: GNSMessage?) in // Send a local notification if not in the foreground. if UIApplication.shared.applicationState != .active { let localNotification = UILocalNotification() localNotification.alertBody = "Message received" UIApplication.shared.presentLocalNotificationNow(localNotification) } // Process the new message... }