Nearby Messages API to interfejs API typu publikuj-subskrybuj, który umożliwia urządzeniom w pobliżu wymianę małych pakietów danych. Gdy urządzenie opublikuje wiadomość, urządzenia w pobliżu mogą ją odebrać. Aby zachować dobrą wydajność, rozmiar wiadomości powinien być stosunkowo mały. Ta usługa nie jest przeznaczona do wymiany większych obiektów, takich jak zdjęcia i filmy.
Zestaw urządzeń w pobliżu jest określany przez wymianę małych tokenów przez Bluetooth i dźwięk o częstotliwości bliskiej ultradźwiękom (niesłyszalny). Gdy urządzenie wykryje token z urządzenia w pobliżu, wysyła go na serwer Nearby Messages, aby go zweryfikować i sprawdzić, czy są jakieś wiadomości do dostarczenia w ramach bieżącego zestawu subskrypcji aplikacji.
Aplikacja może kontrolować zestaw mediów używanych do wykrywania urządzeń oraz to, czy media są używane do rozgłaszania tokenów lub skanowania w ich poszukiwaniu. Domyślnie rozgłaszanie i skanowanie odbywa się we wszystkich mediach. Aby wykrywać urządzenia w podzbiorze mediów i kontrolować, czy rozgłaszać, czy skanować, musisz przekazać dodatkowe parametry podczas tworzenia publikacji i subskrypcji.
Ta biblioteka działa w iOS 7 i nowszych wersjach oraz jest tworzona za pomocą pakietu SDK na 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 nie jest uwierzytelniana, dlatego musisz podać publiczny klucz interfejsu API na iOS. Możesz go utworzyć za pomocą wpisu w Konsoli Google Developers dla swojego projektu.
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, jak opublikować wiadomość zawierającą nazwę. Publikacja jest aktywna tak długo, jak długo istnieje obiekt publikacji. Aby zatrzymać 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 pokazuje, jak subskrybować wszystkie nazwy udostępnione przez poprzedni fragment kodu publikacji. Subskrypcja jest aktywna tak długo, jak długo istnieje obiekt subskrypcji. Aby zatrzymać subskrybowanie, zwolnij obiekt subskrypcji.
Procedura obsługi znalezionych wiadomości jest wywoływana, gdy zostaną wykryte urządzenia w pobliżu, które publikują wiadomości. Procedura obsługi utraconych wiadomości jest wywoływana, gdy wiadomość nie jest już obserwowana (urządzenie wyszło poza zasięg lub nie publikuje już wiadomości).
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
})
Media wykrywania
Domyślnie do wykrywania urządzeń w pobliżu będą używane oba media (dźwięk i Bluetooth), a oba media będą rozgłaszać i skanować. W niektórych przypadkach musisz dodać te wpisy do pliku Info.plist aplikacji:
Jeśli Twoja aplikacja skanuje za pomocą dźwięku, dodaj ciąg
NSMicrophoneUsageDescriptionopisujący, dlaczego będziesz używać mikrofonu. Na przykład „Mikrofon nasłuchuje anonimowych tokenów z urządzeń w pobliżu”.Jeśli Twoja aplikacja rozgłasza za pomocą BLE, dodaj ciąg
NSBluetoothPeripheralUsageDescriptionopisujący, dlaczego będziesz reklamować się za pomocą BLE. Na przykład „Anonimowy token jest rozgłaszany przez Bluetooth, aby wykrywać urządzenia w pobliżu”.
W niektórych przypadkach aplikacja może potrzebować używać tylko jednego z mediów i nie musi rozgłaszać ani skanować w tym medium.
Na przykład aplikacja, która ma łączyć się z dekoderem rozgłaszającym tylko dźwięk, musi skanować tylko dźwięk, aby go wykryć. Poniższy fragment kodu pokazuje, jak opublikować wiadomość na tym dekoderze, używając do wykrywania tylko 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 zapisuje w konsoli ważne zdarzenia wewnętrzne, które mogą być przydatne do śledzenia problemów, które mogą wystąpić podczas integrowania Nearby Messages z aplikacją. Jeśli skontaktujesz się z nami w sprawie pomocy technicznej, poprosimy Cię o te logi.
Włącz je przed utworzeniem 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ń do korzystania z funkcji W pobliżu
Aby włączyć wykrywanie urządzeń, wymagana jest zgoda użytkownika. Wskazuje na to stan uprawnień do korzystania z funkcji W pobliżu. Przy pierwszym wywołaniu funkcji tworzenia publikacji lub subskrypcji użytkownikowi wyświetla się okno z prośbą o zgodę na przetwarzanie danych osobowych. Jeśli użytkownik nie wyrazi zgody, wykrywanie urządzeń nie będzie działać. W takim przypadku aplikacja powinna wyświetlić komunikat przypominający użytkownikowi, że wykrywanie urządzeń jest wyłączone. Stan uprawnień jest przechowywany w NSUserDefaults.
Poniższy fragment kodu pokazuje, jak subskrybować stan uprawnień. Procedura obsługi zmiany stanu uprawnień jest wywoływana za każdym razem, gdy stan się zmienia, ale nie jest wywoływana po raz pierwszy, dopóki użytkownik nie przyzna lub nie odmówi uprawnień. Aby zatrzymać subskrybowanie, 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, jak uzyskać i ustawić stan 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żytkownika, które mają wpływ na funkcję W pobliżu
Jeśli użytkownik odmówi dostępu do mikrofonu lub uprawnień do korzystania z Bluetootha albo wyłączy Bluetootha, funkcja W pobliżu nie będzie działać prawidłowo lub w ogóle nie będzie działać. W takich przypadkach aplikacja powinna wyświetlić komunikat informujący użytkownika, że działanie funkcji W pobliżu jest utrudnione. Poniższy fragment kodu pokazuje, jak śledzić stan tych ustawień użytkownika, przekazując procedury 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 z prośbą o uprawnienia do korzystania z funkcji W pobliżu
W zależności od parametrów przekazywanych do publikacji i subskrypcji iOS może poprosić o różne uprawnienia, zanim zezwoli na działanie funkcji W pobliżu. Na przykład domyślna strategia nasłuchuje danych przesyłanych przez dźwięk o częstotliwości bliskiej ultradźwiękom, więc iOS poprosi o uprawnienia do korzystania z mikrofonu. W takich przypadkach funkcja W pobliżu wyświetli okno „preflight”, które wyjaśnia, dlaczego użytkownik jest proszony o przyznanie uprawnień.
Jeśli chcesz wyświetlać niestandardowe okno „preflight”, ustaw parametr permissionRequestHandler na niestandardowy blok w parametrach publikacji lub subskrypcji. Po odpowiedzi użytkownika niestandardowy blok musi wywołać blok permissionHandler. Poniższy 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, które używają BLE do wykrywania urządzeń, mogą działać w tle. Jeśli zdecydujesz się na używanie trybu działania w tle, musisz pamiętać o tych kwestiach:
- Operacje w tle muszą używać tylko medium BLE – dźwięk nie jest obsługiwany.
- Działanie BLE w tle wiąże się z dodatkowym zużyciem baterii. Zużycie jest niewielkie, ale przed podjęciem decyzji o używaniu trybu działania w tle warto je zmierzyć.
- iOS poprosi użytkownika o zgodę na reklamowanie się za pomocą BLE w tle.
Aby dodać tryb działania w tle do publikacji lub subskrypcji, wykonaj te dodatkowe czynności:
Włącz tryb działania w tle i tylko BLE w publikacji lub subskrypcji, przekazując prawidłowo skonfigurowany obiekt
GNSStrategy. Poniższy 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 pliku
Info.plistaplikacji:Wpisy
UIBackgroundModes:bluetooth-centraldo skanowania BLE w tle. Jest to wymagane tylko wtedy, gdy tryb wykrywania obejmuje skanowanie (domyślnie tak jest).bluetooth-peripheraldo rozgłaszania BLE w tle. Jest to wymagane tylko wtedy, gdy tryb wykrywania obejmuje rozgłaszanie (domyślnie tak jest).
Ciąg
NSBluetoothPeripheralUsageDescriptionopisujący, dlaczego będziesz rozgłaszać za pomocą BLE. Na przykład „Anonimowy token jest rozgłaszany przez Bluetooth, aby wykrywać urządzenia w pobliżu”. Szczegółowe informacje znajdziesz w dokumentacji Apple.
Gdy aplikacja działa w tle, system może ją w każdej chwili zamknąć. Jeśli tryb działania w tle jest ustawieniem, które użytkownik może włączyć lub wyłączyć, aplikacja powinna wykonać te czynności:
- Zapisz wartość trybu działania w tle w
NSUserDefaultsza każdym razem, gdy użytkownik ją zmieni. - Po uruchomieniu odczytaj ją z
NSUserDefaultsi przywróć publikacje lub subskrypcje funkcji W pobliżu, jeśli tryb działania w tle jest włączony.
- Zapisz wartość trybu działania w tle w
Powiadomienia w tle
Jeśli chcesz, aby aplikacja powiadamiała użytkownika, gdy subskrypcja otrzyma wiadomość w tle, możesz użyć powiadomień lokalnych.
Aby dodać je do aplikacji:
Zarejestruj powiadomienia lokalne podczas uruchamiania:
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 procedurze obsługi znalezionych wiadomości 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... }