Opublikuj i zasubskrybuj

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.

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