Publier et s'abonner

L'API Nearby Messages est une API de publication/abonnement qui permet aux appareils à proximité d'échanger de petites charges utiles de données. Une fois qu'un appareil publie un message, les appareils à proximité peuvent le recevoir. La taille des messages doit être relativement petite pour maintenir de bonnes performances. Ce service n'est pas destiné à l'échange d'objets plus volumineux tels que des photos et des vidéos.

L'ensemble des appareils à proximité est déterminé par l'échange de petits jetons via Bluetooth et un son quasi-ultrasonique (inaudible). Lorsqu'un appareil détecte un jeton provenant d'un appareil à proximité, il l'envoie au serveur Nearby Messages pour le valider et vérifier s'il existe des messages à distribuer pour l'ensemble actuel d'abonnements de l'application.

Une application peut contrôler l'ensemble des supports utilisés pour la détection des appareils, et si les supports sont utilisés pour diffuser des jetons et/ou rechercher des jetons. Par défaut, la diffusion et la recherche sont effectuées sur tous les supports. Pour effectuer une détection sur un sous-ensemble de supports et contrôler si vous souhaitez diffuser ou rechercher, vous devez transmettre des paramètres supplémentaires lorsque vous créez des publications et des abonnements.

Cette bibliothèque s'exécute sur iOS 7 et versions ultérieures, et est compilée avec le SDK iOS 8.

Créer un gestionnaire de messages

Ce code crée un objet de gestionnaire de messages, qui vous permet de publier et de vous abonner. L'échange de messages n'est pas authentifié. Vous devez donc fournir une clé API publique pour iOS. Vous pouvez en créer une à l'aide de l'entrée Google Developers Console pour votre projet.

Objective-C

#import <GNSMessages.h>

GNSMessageManager *messageManager =
    [[GNSMessageManager alloc] initWithAPIKey:@"API_KEY"];

Swift

let messageManager = GNSMessageManager(APIKey: "API_KEY")

Publier un message

Cet extrait de code montre comment publier un message contenant un nom. La publication est active tant que l'objet de publication existe. Pour arrêter la publication, libérez l'objet de publication.

Objective-C

id<GNSPublication> publication =
    [messageManager publicationWithMessage:[GNSMessage messageWithContent:[name dataUsingEncoding:NSUTF8StringEncoding]]];

Swift

let publication =
    messageManager.publication(with: GNSMessage(content: name.data(using: .utf8)))

S'abonner à des messages

Cet extrait de code montre comment s'abonner à tous les noms partagés par l'extrait de publication précédent. L'abonnement est actif tant que les objets d'abonnement existent. Pour arrêter l'abonnement, libérez l'objet d'abonnement.

Le gestionnaire de messages trouvés est appelé lorsque des appareils à proximité qui publient des messages sont détectés. Le gestionnaire de messages perdus est appelé lorsqu'un message n'est plus observé (l'appareil est hors de portée ou ne publie plus le message).

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

Supports de détection

Par défaut, les deux supports (audio et Bluetooth) sont utilisés pour détecter les appareils à proximité, et les deux supports diffusent et recherchent. Dans certains cas, vous devez ajouter les entrées suivantes au fichier Info.plist de votre application :

  • Si votre application effectue une recherche à l'aide de l'audio, ajoutez NSMicrophoneUsageDescription, qui est une chaîne décrivant pourquoi vous utiliserez le micro. Par exemple, "Le micro écoute les jetons anonymes provenant d'appareils à proximité."

  • Si votre application diffuse à l'aide de BLE, ajoutez NSBluetoothPeripheralUsageDescription, qui est une chaîne décrivant pourquoi vous ferez de la publicité sur BLE. Par exemple, "Un jeton anonyme est diffusé via Bluetooth pour détecter les appareils à proximité."

Dans certains cas, votre application peut n'avoir besoin d'utiliser qu'un seul des supports, et il n'est pas nécessaire qu'elle effectue à la fois la diffusion et la recherche sur ce support.

Par exemple, une application conçue pour se connecter à un décodeur qui diffuse uniquement du contenu audio n'a besoin que d'effectuer une recherche audio pour le détecter. L'extrait suivant montre comment publier un message sur ce décodeur en utilisant uniquement la recherche audio pour la détection :

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

Activer la journalisation de débogage

La journalisation de débogage affiche les événements internes importants dans la console, ce qui peut être utile pour identifier les problèmes que vous pouvez rencontrer lors de l'intégration de Nearby Messages dans votre application. Nous vous demanderons ces journaux si vous nous contactez pour obtenir une assistance technique.

Vous devez l'activer avant de créer un gestionnaire de messages. Cet extrait de code montre comment activer la journalisation de débogage :

Objective-C

[GNSMessageManager setDebugLoggingEnabled:YES];

Swift

GNSMessageManager.setDebugLoggingEnabled(true)

Suivre l'état de l'autorisation Nearby

Le consentement de l'utilisateur est requis pour activer la détection des appareils. Ceci est indiqué par l'état de l'autorisation Nearby. Lors du premier appel pour créer une publication ou un abonnement, une boîte de dialogue de consentement s'affiche pour l'utilisateur. Si l'utilisateur ne donne pas son consentement, la détection des appareils ne fonctionnera pas. Dans ce cas, votre application doit afficher un message pour rappeler à l'utilisateur que la détection des appareils est désactivée. L'état de l'autorisation est stocké dans NSUserDefaults.

L'extrait suivant montre comment s'abonner à l'état de l'autorisation. Le gestionnaire d'état de l'autorisation modifié est appelé chaque fois que l'état change, et il n'est pas appelé la première fois tant que l'utilisateur n'a pas accordé ou refusé l'autorisation. Libérez l'objet d'autorisation pour arrêter l'abonnement.

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

Votre application peut permettre à l'utilisateur de modifier l'état de l'autorisation, par exemple à l'aide d'un bouton bascule sur une page de paramètres.

Voici un exemple de récupération et de définition de l'état de l'autorisation.

Objective-C

BOOL permissionState = [GNSPermission isGranted];
[GNSPermission setGranted:!permissionState];  // toggle the state

Swift

let permissionState = GNSPermission.isGranted()
GNSPermission.setGranted(!permissionState)  // toggle the state

Suivre les paramètres utilisateur qui affectent Nearby

Si l'utilisateur a refusé l'autorisation d'utiliser le micro, l'autorisation d'utiliser le Bluetooth ou a désactivé le Bluetooth, Nearby ne fonctionnera pas aussi bien, voire pas du tout. Dans ce cas, votre application doit afficher un message pour avertir l'utilisateur que les opérations de Nearby sont entravées. L'extrait suivant montre comment suivre l'état de ces paramètres utilisateur en transmettant des gestionnaires lors de la création du gestionnaire de messages :

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

Ignorer la boîte de dialogue d'autorisation Nearby

En fonction des paramètres que vous transmettez à vos publications et abonnements, iOS peut demander différentes autorisations avant d'autoriser le fonctionnement de Nearby. Par exemple, la stratégie par défaut écoute les données transmises sur un son quasi-ultrasonique. iOS demandera donc l'autorisation d'utiliser le micro. Dans ce cas, Nearby affiche une boîte de dialogue "prévol" qui explique pourquoi l'utilisateur est invité à accorder l'autorisation.

Si vous souhaitez fournir une boîte de dialogue "prévol" personnalisée, définissez le paramètre permissionRequestHandler sur un bloc personnalisé dans les paramètres de publication ou d'abonnement. Votre bloc personnalisé doit appeler le bloc permissionHandler une fois que l'utilisateur a répondu. L'extrait suivant montre comment procéder pour une publication :

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

Opération en arrière-plan

Les publications et les abonnements qui utilisent BLE pour la détection des appareils peuvent fonctionner en arrière-plan. Voici quelques points à prendre en compte lorsque vous décidez d'utiliser le mode arrière-plan :

  • Les opérations en arrière-plan ne doivent utiliser que le support BLE. L'audio n'est pas compatible.
  • Le BLE en arrière-plan entraîne un coût de batterie supplémentaire. Le coût est faible, mais vous devez le mesurer avant de décider d'utiliser le mode arrière-plan.
  • iOS demandera à l'utilisateur l'autorisation de diffuser via BLE en arrière-plan.

Pour ajouter le mode arrière-plan à une publication ou à un abonnement, procédez comme suit :

  • Activez le mode arrière-plan et le BLE uniquement dans votre publication ou votre abonnement en transmettant un objet GNSStrategy correctement configuré. L'extrait suivant montre comment procéder pour un abonnement :

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

  • Ajoutez ces entrées au fichier Info.plist de votre application :

    • Entrées UIBackgroundModes :

      • bluetooth-central pour la recherche BLE en arrière-plan. Nécessaire uniquement lorsque le mode de détection inclut la recherche, ce qui est le cas par défaut.
      • bluetooth-peripheral pour la publicité BLE en arrière-plan. Nécessaire uniquement lorsque le mode de détection inclut la diffusion, ce qui est le cas par défaut.
    • Chaîne NSBluetoothPeripheralUsageDescription décrivant pourquoi vous ferez de la publicité sur BLE. Par exemple, "Un jeton anonyme est diffusé via Bluetooth pour détecter les appareils à proximité." Pour en savoir plus, consultez la documentation d'Apple.

  • Votre application peut être arrêtée à tout moment par le système en arrière-plan. Si le mode arrière-plan est un paramètre que l'utilisateur peut activer ou désactiver, votre application doit procéder comme suit :

    • Enregistrez la valeur du mode arrière-plan dans NSUserDefaults chaque fois que l'utilisateur la modifie.
    • Au démarrage, lisez-la à partir de NSUserDefaults et restaurez les publications et/ou abonnements Nearby si le mode arrière-plan est activé.

Notifications en arrière-plan

Si vous souhaitez que votre application informe l'utilisateur lorsqu'un abonnement reçoit un message en arrière-plan, vous pouvez utiliser des notifications locales.

Pour les ajouter à votre application, procédez comme suit :

  • Enregistrez-vous pour les notifications locales au démarrage :

    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))
    

  • Envoyez une notification locale dans le gestionnaire de messages trouvés de votre abonnement :

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