Compartir por


Tutorial: Envío de notificaciones push localizadas a iOS mediante Azure Notification Hubs

En este tutorial se muestra cómo usar la característica de plantillas de Azure Notification Hubs para difundir notificaciones de noticias de última hora localizadas por lenguaje y dispositivo. En este tutorial comenzará con la aplicación de iOS que se creó en Uso de Notification Hubs para enviar noticias de última hora. Una vez que lo haya completado, podrá registrarse en las categorías que le interesen, especificar un idioma para recibir las notificaciones y recibir solo notificaciones push para las categorías seleccionadas en dicho idioma.

Este escenario tiene dos partes:

  • La aplicación iOS permite que los dispositivos cliente especifiquen un idioma y que se suscriban a distintas categorías de noticias de última hora;
  • El back-end difunde las notificaciones mediante las características etiqueta y plantilla de Azure Notification Hubs.

En este tutorial, realizará los siguientes pasos:

  • Actualizar la interfaz de usuario de la aplicación
  • Crear la aplicación de iOS
  • Enviar notificaciones de plantillas localizadas desde la aplicación de consola .NET
  • Enviar notificaciones de plantillas localizadas desde el dispositivo

Información general

En el tutorial Uso de Notification Hubs para enviar noticias de última hora creó una aplicación que utilizó etiquetas para suscribirse a notificaciones para distintas categorías de noticias. Sin embargo, muchas aplicaciones están dirigidas a varios mercados y requieren localización. Esto significa que el contenido de las notificaciones mismas se debe localizar y entregar al conjunto de dispositivos correcto. En este tutorial se explica cómo usar la característica plantilla de Notification Hubs para entregar fácilmente notificaciones de noticias de última hora localizadas.

Nota

Una forma de enviar notificaciones localizadas es crear varias versiones de cada etiqueta. Por ejemplo, para admitir inglés, francés y chino mandarín, necesitaría tres etiquetas distintas para noticias mundiales: "world_en", "world_fr" y "world_ch". Luego tendría que enviar una versión localizada de las noticias mundiales a cada una de estas etiquetas. En este tema se usan plantillas para evitar la proliferación de etiquetas y el requisito de enviar varios mensajes.

Las plantillas son una forma de especificar la manera en que un dispositivo específico debe recibir una notificación. La plantilla especifica el formato de carga exacto haciendo referencia a las propiedades que forman parte del mensaje enviado por el back-end de la aplicación. En su caso, se envía un mensaje independiente de la configuración regional que contiene todos los idiomas compatibles:

{
    "News_English": "...",
    "News_French": "...",
    "News_Mandarin": "..."
}

Esto garantizará que los dispositivos se registren con una plantilla que hace referencia a la propiedad correcta. Por ejemplo, una aplicación iOS que quiera registrarse para noticias en francés se registrará con la siguiente sintaxis:

{
    aps: {
        alert: "$(News_French)"
    }
}

Para más información sobre el uso de plantillas, vea el artículo Plantillas.

Requisitos previos

Actualizar la interfaz de usuario de la aplicación

En esta sección, se modificará la aplicación de noticias de última hora que creó en el tema Uso de Notification Hubs para enviar noticias de última hora para enviar noticias de última hora localizadas con plantillas.

En MainStoryboard_iPhone.storyboard, agregue un control segmentado con los tres idiomas: inglés, francés y chino mandarín.

Creación del guion gráfico de interfaz de usuario de iOS

A continuación, asegúrese de agregar un IBOutlet en ViewController.h tal como se muestra en la imagen siguiente:

Creación de salidas para los modificadores

Crear la aplicación de iOS

  1. En Notification.h, agregue el método retrieveLocale, modifique el almacén y suscríbase a métodos tal como se muestra en el siguiente código:

    - (void) storeCategoriesAndSubscribeWithLocale:(int) locale categories:(NSSet*) categories completion: (void (^)(NSError* error))completion;
    
    - (void) subscribeWithLocale:(int) locale categories:(NSSet*) categories completion:(void (^)(NSError *))completion;
    
    - (NSSet*) retrieveCategories;
    
    - (int) retrieveLocale;
    

    En Notification.m, modifique el método storeCategoriesAndSubscribe agregando el parámetro locale y almacenándolo en los valores predeterminados del usuario:

    - (void) storeCategoriesAndSubscribeWithLocale:(int) locale categories:(NSSet *)categories completion:(void (^)(NSError *))completion {
        NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
        [defaults setValue:[categories allObjects] forKey:@"BreakingNewsCategories"];
        [defaults setInteger:locale forKey:@"BreakingNewsLocale"];
        [defaults synchronize];
    
        [self subscribeWithLocale: locale categories:categories completion:completion];
    }
    

    Luego modifique el método subscribe para incluir la configuración regional:

    - (void) subscribeWithLocale: (int) locale categories:(NSSet *)categories completion:(void (^)(NSError *))completion{
        SBNotificationHub* hub = [[SBNotificationHub alloc] initWithConnectionString:@"<connection string>" notificationHubPath:@"<hub name>"];
    
        NSString* localeString;
        switch (locale) {
            case 0:
                localeString = @"English";
                break;
            case 1:
                localeString = @"French";
                break;
            case 2:
                localeString = @"Mandarin";
                break;
        }
    
        NSString* template = [NSString stringWithFormat:@"{\"aps\":{\"alert\":\"$(News_%@)\"},\"inAppMessage\":\"$(News_%@)\"}", localeString, localeString];
    
        [hub registerTemplateWithDeviceToken:self.deviceToken name:@"localizednewsTemplate" jsonBodyTemplate:template expiryTemplate:@"0" tags:categories completion:completion];
    }
    

    Utilice el método registerTemplateWithDeviceToken, en lugar de registerNativeWithDeviceToken. Al registrarse para obtener una plantilla, tiene que proporcionar la plantilla JSON y también un nombre para la plantilla (dado que puede que la aplicación quiera registrar diferentes plantillas). Asegúrese de registrar sus categorías como etiquetas, ya que queremos asegurarnos de recibir las notificaciones para esas noticias.

    Agregue un método para recuperar la configuración regional a partir de los ajustes predeterminados del usuario:

    - (int) retrieveLocale {
        NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
    
        int locale = [defaults integerForKey:@"BreakingNewsLocale"];
    
        return locale < 0?0:locale;
    }
    
  2. Ahora que ha modificado la clase Notifications, debe asegurarse de que la clase ViewController utiliza la nueva UISegmentControl. Agregue la siguiente línea en el método viewDidLoad para asegurarse de mostrar la configuración regional actualmente seleccionada:

    self.Locale.selectedSegmentIndex = [notifications retrieveLocale];
    

    Después, en el método subscribe, cambie la llamada a storeCategoriesAndSubscribe al código siguiente:

    [notifications storeCategoriesAndSubscribeWithLocale: self.Locale.selectedSegmentIndex categories:[NSSet setWithArray:categories] completion: ^(NSError* error) {
        if (!error) {
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Notification" message:
                                    @"Subscribed!" delegate:nil cancelButtonTitle:
                                    @"OK" otherButtonTitles:nil, nil];
            [alert show];
        } else {
            NSLog(@"Error subscribing: %@", error);
        }
    }];
    
  3. Finalmente, debe actualizar el método didRegisterForRemoteNotificationsWithDeviceToken en AppDelegate.m, para que pueda actualizar correctamente el registro cuando se inicie la aplicación. Cambie la llamada al método subscribe de notificaciones con el código siguiente:

    NSSet* categories = [self.notifications retrieveCategories];
    int locale = [self.notifications retrieveLocale];
    [self.notifications subscribeWithLocale: locale categories:categories completion:^(NSError* error) {
        if (error != nil) {
            NSLog(@"Error registering for notifications: %@", error);
        }
    }];
    

(Opcional) Envíe notificaciones de plantillas localizadas desde la aplicación de consola .NET.

Cuando se envían notificaciones de plantilla, solo necesita proporcionar un conjunto de propiedades. En este escenario, el conjunto de propiedades contiene la versión localizada de las noticias actuales.

{
    "News_English": "World News in English!",
    "News_French": "World News in French!",
    "News_Mandarin": "World News in Mandarin!"
}

Envío de notificaciones mediante una aplicación de consola de C#

En esta sección se muestra cómo enviar notificaciones con una aplicación de consola. El código difunde las notificaciones a los dispositivos iOS y a la Tienda Windows. Modifique el método SendTemplateNotificationAsync en la aplicación de consola que creó anteriormente con el código siguiente:

private static async void SendTemplateNotificationAsync()
{
    // Define the notification hub.
    NotificationHubClient hub = NotificationHubClient.CreateClientFromConnectionString(
            "<connection string with full access>", "<hub name>");

    // Apple requires the apns-push-type header for all requests
    var headers = new Dictionary<string, string> {{"apns-push-type", "alert"}};

    // Sending the notification as a template notification. All template registrations that contain 
    // "messageParam" or "News_<local selected>" and the proper tags will receive the notifications. 
    // This includes APNS, GCM, WNS, and MPNS template registrations.
    Dictionary<string, string> templateParams = new Dictionary<string, string>();

    // Create an array of breaking news categories.
    var categories = new string[] { "World", "Politics", "Business", "Technology", "Science", "Sports"};
    var locales = new string[] { "English", "French", "Mandarin" };

    foreach (var category in categories)
    {
        templateParams["messageParam"] = "Breaking " + category + " News!";

        // Sending localized News for each tag too...
        foreach( var locale in locales)
        {
            string key = "News_" + locale;

            // Your real localized news content would go here.
            templateParams[key] = "Breaking " + category + " News in " + locale + "!";
        }

        await hub.SendTemplateNotificationAsync(templateParams, category);
    }
}

El método SendTemplateNotificationAsync entrega las noticias localizadas a todos los dispositivos, independientemente de la plataforma. El centro de notificaciones crea y entrega la carga nativa correcta a todos los dispositivos suscritos a una etiqueta específica.

Envío de la notificación con Mobile Services

En el programador de Mobile Services, use el script siguiente:

var azure = require('azure');
var notificationHubService = azure.createNotificationHubService('<hub name>', '<connection string with full access>');
var notification = {
        "News_English": "World News in English!",
        "News_French": "World News in French!",
        "News_Mandarin", "World News in Mandarin!"
}
notificationHubService.send('World', notification, function(error) {
    if (!error) {
        console.warn("Notification successful");
    }
});

(Opcional) Enviar notificaciones de plantillas localizadas desde el dispositivo

Si no tiene acceso a Visual Studio, o simplemente quiere probar el envío de las notificaciones de plantilla localizadas directamente desde la aplicación del dispositivo. Puede agregar los parámetros de plantilla localizada al método SendNotificationRESTAPI que ha definido en el tutorial anterior.

- (void)SendNotificationRESTAPI:(NSString*)categoryTag
{
    NSURLSession* session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration
                                defaultSessionConfiguration] delegate:nil delegateQueue:nil];

    NSString *json;

    // Construct the messages REST endpoint
    NSURL* url = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@/messages/%@", HubEndpoint,
                                        HUBNAME, API_VERSION]];

    // Generated the token to be used in the authorization header.
    NSString* authorizationToken = [self generateSasToken:[url absoluteString]];

    //Create the request to add the template notification message to the hub
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    [request setHTTPMethod:@"POST"];

    // Add the category as a tag
    [request setValue:categoryTag forHTTPHeaderField:@"ServiceBusNotification-Tags"];

    // Template notification
    json = [NSString stringWithFormat:@"{\"messageParam\":\"Breaking %@ News : %@\","
            \"News_English\":\"Breaking %@ News in English : %@\","
            \"News_French\":\"Breaking %@ News in French : %@\","
            \"News_Mandarin\":\"Breaking %@ News in Mandarin : %@\","
            categoryTag, self.notificationMessage.text,
            categoryTag, self.notificationMessage.text,  // insert English localized news here
            categoryTag, self.notificationMessage.text,  // insert French localized news here
            categoryTag, self.notificationMessage.text]; // insert Mandarin localized news here

    // Signify template notification format
    [request setValue:@"template" forHTTPHeaderField:@"ServiceBusNotification-Format"];

    // JSON Content-Type
    [request setValue:@"application/json;charset=utf-8" forHTTPHeaderField:@"Content-Type"];

    //Authenticate the notification message POST request with the SaS token
    [request setValue:authorizationToken forHTTPHeaderField:@"Authorization"];

    //Add the notification message body
    [request setHTTPBody:[json dataUsingEncoding:NSUTF8StringEncoding]];

    // Send the REST request
    NSURLSessionDataTask* dataTask = [session dataTaskWithRequest:request
                completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
        {
        NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*) response;
            if (error || httpResponse.statusCode != 200)
            {
                NSLog(@"\nError status: %d\nError: %@", httpResponse.statusCode, error);
            }
            if (data != NULL)
            {
                //xmlParser = [[NSXMLParser alloc] initWithData:data];
                //[xmlParser setDelegate:self];
                //[xmlParser parse];
            }
        }];

    [dataTask resume];
}

Pasos siguientes

En este tutorial, se envían notificaciones localizadas a dispositivos iOS. Para aprender a enviar notificaciones push a usuarios específicos de aplicaciones iOS, pase al siguiente tutorial: