Opublikuj i zasubskrybuj

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 NSMicrophoneUsageDescription opisują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 NSBluetoothPeripheralUsageDescription opisują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.plist aplikacji:

    • Wpisy UIBackgroundModes:

      • bluetooth-central do skanowania BLE w tle. Jest to wymagane tylko wtedy, gdy tryb wykrywania obejmuje skanowanie (domyślnie tak jest).
      • bluetooth-peripheral do rozgłaszania BLE w tle. Jest to wymagane tylko wtedy, gdy tryb wykrywania obejmuje rozgłaszanie (domyślnie tak jest).
    • Ciąg NSBluetoothPeripheralUsageDescription opisują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 NSUserDefaults za każdym razem, gdy użytkownik ją zmieni.
    • Po uruchomieniu odczytaj ją z NSUserDefaults i przywróć publikacje lub subskrypcje funkcji W pobliżu, jeśli tryb działania w tle jest włączony.

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...
    }