La API de Nearby Messages es una API de publicación y suscripción que permite que los dispositivos cercanos intercambien cargas útiles pequeñas de datos. Una vez que un dispositivo publica un mensaje, los dispositivos cercanos pueden recibirlo. El tamaño del mensaje debe ser bastante pequeño para mantener un buen rendimiento. Este servicio no está diseñado para intercambiar objetos más grandes, como fotos y videos.
El conjunto de dispositivos cercanos se determina mediante el intercambio de tokens pequeños a través de Bluetooth y audio casi ultrasónico (inaudible). Cuando un dispositivo detecta un token de otro dispositivo cercano, lo envía al servidor de Nearby Messages para validarlo y verificar si hay mensajes para entregar al conjunto actual de suscripciones de la aplicación.
Una aplicación puede controlar el conjunto de medios que se usan para el descubrimiento de dispositivos y si los medios se usan para transmitir tokens o buscar tokens. De forma predeterminada, la transmisión y el análisis se realizan en todos los medios. Para realizar el descubrimiento en un subconjunto o en medios, y para controlar si se debe transmitir o analizar, debes pasar parámetros adicionales cuando creas publicaciones y suscripciones.
Esta biblioteca se ejecuta en iOS 7 y versiones posteriores, y se compila con el SDK de iOS 8.
Cómo crear un administrador de mensajes
Este código crea un objeto de administrador de mensajes, que te permite publicar y suscribirte. El intercambio de mensajes no está autenticado, por lo que debes proporcionar una clave de API pública para iOS. Puedes crear uno con la entrada de Google Developers Console para tu proyecto.
Objective-C
#import <GNSMessages.h>
GNSMessageManager *messageManager =
[[GNSMessageManager alloc] initWithAPIKey:@"API_KEY"];
Swift
let messageManager = GNSMessageManager(APIKey: "API_KEY")
Cómo publicar un mensaje
En este fragmento de código, se muestra cómo publicar un mensaje que contiene un nombre. La publicación está activa mientras exista el objeto de publicación. Para detener la publicación, libera el objeto de publicación.
Objective-C
id<GNSPublication> publication =
[messageManager publicationWithMessage:[GNSMessage messageWithContent:[name dataUsingEncoding:NSUTF8StringEncoding]]];
Swift
let publication =
messageManager.publication(with: GNSMessage(content: name.data(using: .utf8)))
Cómo suscribirse a los mensajes
En este fragmento de código, se muestra cómo suscribirse a todos los nombres que se comparten en el fragmento de publicación anterior. La suscripción está activa mientras existan los objetos de suscripción. Para detener la suscripción, libera el objeto de suscripción.
Se llama al controlador de mensajes encontrados cuando se descubren dispositivos cercanos que publican mensajes. Se llama al controlador de mensajes perdidos cuando ya no se observa un mensaje (el dispositivo salió del rango o ya no publica el mensaje).
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
})
Medios de descubrimiento
De forma predeterminada, se usarán ambos medios (audio y Bluetooth) para detectar dispositivos cercanos, y ambos medios transmitirán y buscarán. En algunos casos, debes agregar las siguientes entradas al archivo Info.plist
de tu app:
Si tu app realiza análisis con audio, agrega
NSMicrophoneUsageDescription
, que es una cadena que describe por qué usarás el micrófono. Por ejemplo, "El micrófono escucha tokens anónimos de dispositivos cercanos".Si tu app transmite con BLE, agrega
NSBluetoothPeripheralUsageDescription
, que es una cadena que describe por qué publicarás anuncios en BLE. Por ejemplo, "Se anuncia un token anónimo a través de Bluetooth para detectar dispositivos cercanos".
En algunos casos, es posible que tu app solo necesite usar uno de los medios y no necesite transmitir ni analizar en ese medio.
Por ejemplo, una app diseñada para conectarse a un decodificador que transmite solo audio necesita buscarlo en el audio para detectarlo. En el siguiente fragmento, se muestra cómo publicar un mensaje en ese decodificador usando solo la exploración de audio para el descubrimiento:
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
})
})
Cómo habilitar el registro de depuración
El registro de depuración imprime eventos internos significativos en la consola que pueden ser útiles para rastrear problemas que puedes encontrar cuando integras Nearby Messages en tu app. Te pediremos estos registros si te comunicas con nosotros para obtener asistencia técnica.
Debes habilitarlo antes de crear un administrador de mensajes. En este fragmento de código, se muestra cómo habilitar el registro de depuración:
Objective-C
[GNSMessageManager setDebugLoggingEnabled:YES];
Swift
GNSMessageManager.setDebugLoggingEnabled(true)
Cómo hacer un seguimiento del estado del permiso de dispositivos cercanos
Se requiere el consentimiento del usuario para habilitar el descubrimiento de dispositivos. Esto se indica con el estado del permiso de Nearby. En la primera llamada para crear una publicación o suscripción, se le muestra al usuario un diálogo de consentimiento. Si el usuario no otorga su consentimiento, no funcionará el descubrimiento de dispositivos. En este caso, tu app debe mostrar un mensaje para recordarle al usuario que la detección de dispositivos está inhabilitada. El estado del permiso se almacena en NSUserDefaults
.
En el siguiente fragmento, se muestra cómo suscribirse al estado del permiso. Se llama al controlador de cambio de estado de permiso cada vez que cambia el estado, y no se llama la primera vez hasta que el usuario haya otorgado o denegado el permiso. Libera el objeto de permiso para dejar de suscribirte.
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
})
Tu app puede proporcionar una forma para que el usuario cambie el estado del permiso, por ejemplo, con un interruptor de activación en una página de configuración.
A continuación, se muestra un ejemplo de cómo obtener y establecer el estado del permiso.
Objective-C
BOOL permissionState = [GNSPermission isGranted];
[GNSPermission setGranted:!permissionState]; // toggle the state
Swift
let permissionState = GNSPermission.isGranted()
GNSPermission.setGranted(!permissionState) // toggle the state
Seguimiento de la configuración del usuario que afecta a Nearby
Si el usuario rechazó el permiso del micrófono o el permiso de Bluetooth, o bien desactivó el Bluetooth, Nearby no funcionará tan bien o podría no funcionar en absoluto. En estos casos, tu app debe mostrar un mensaje que alerte al usuario de que se están obstaculizando las operaciones de Nearby. En el siguiente fragmento, se muestra cómo hacer un seguimiento del estado de estos parámetros de configuración del usuario pasando controladores cuando se crea el administrador de mensajes:
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
}
})
Cómo anular el diálogo de permiso de Nearby
Según los parámetros que pases a tus publicaciones y suscripciones, es posible que iOS solicite varios permisos antes de permitir que Nearby funcione. Por ejemplo, la estrategia predeterminada escucha los datos transmitidos en audio casi ultrasónico, por lo que iOS pedirá permiso para usar el micrófono. En estos casos, la función Cerca mostrará un diálogo previo que explica por qué se le pide al usuario que otorgue el permiso.
Si deseas proporcionar un diálogo personalizado de "verificación previa", establece el parámetro permissionRequestHandler
en un bloque personalizado en los parámetros de publicación o suscripción. Tu bloque personalizado debe llamar al bloque permissionHandler
después de que el usuario haya respondido. En el siguiente fragmento, se muestra cómo hacerlo para una publicación:
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.
}
})
Operación en segundo plano
Las publicaciones y suscripciones que usan BLE para la detección de dispositivos pueden funcionar en segundo plano. A continuación, se indican algunos aspectos que debes tener en cuenta cuando decidas usar el modo en segundo plano:
- Las operaciones en segundo plano solo deben usar el medio BLE; no se admite el audio.
- Hay un costo adicional de batería para el BLE en segundo plano. El costo es bajo, pero debes medirlo antes de decidir usar el modo en segundo plano.
- iOS le pedirá permiso al usuario para mostrar anuncios a través de BLE en segundo plano.
Para agregar el modo en segundo plano a una publicación o suscripción, sigue estos pasos adicionales:
Habilita el modo en segundo plano y el modo solo BLE en tu publicación o suscripción pasando un objeto
GNSStrategy
configurado correctamente. En el siguiente fragmento, se muestra cómo hacerlo para una suscripción: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 }) })
Agrega estas entradas al archivo
Info.plist
de tu app:Entradas
UIBackgroundModes
:bluetooth-central
para la búsqueda de BLE en segundo plano. Solo se necesita cuando el modo de descubrimiento incluye el análisis, lo que hace de forma predeterminada.bluetooth-peripheral
para la publicidad de BLE en segundo plano Solo se necesita cuando el modo de descubrimiento incluye la transmisión, lo que sucede de forma predeterminada.
Cadena
NSBluetoothPeripheralUsageDescription
que describe por qué publicarás anuncios en BLE. Por ejemplo, "Se anuncia un token anónimo a través de Bluetooth para descubrir dispositivos cercanos". Para obtener más información, consulta la documentación de Apple.
El sistema puede detener tu app en cualquier momento mientras se ejecuta en segundo plano. Si el modo en segundo plano es un parámetro de configuración que el usuario puede habilitar o inhabilitar, tu app debe hacer lo siguiente:
- Guarda el valor del modo en segundo plano en
NSUserDefaults
cada vez que el usuario lo cambie. - Al inicio, léelo desde
NSUserDefaults
y restablece las publicaciones o suscripciones cercanas si el modo en segundo plano está habilitado.
- Guarda el valor del modo en segundo plano en
Notificaciones en segundo plano
Si quieres que tu app notifique al usuario cuando una suscripción reciba un mensaje en segundo plano, puedes usar notificaciones locales.
Sigue estos pasos para agregarlos a tu app:
Regístrate para recibir notificaciones locales en el inicio:
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))
Envía una notificación local en el controlador message-found de tu suscripción:
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... }