Tutorial: Enviar notificações push localizadas para iOS com os Hubs de Notificação do Azure

Este tutorial mostra-lhe como utilizar a funcionalidade modelos dos Hubs de Notificação do Azure para transmitir notificações de notícias de última hora que foram localizadas por idioma e dispositivo. Neste tutorial, vai começar com a aplicação iOS criada em Utilizar Hubs de Notificação para enviar notícias de última hora. Quando terminar, pode registar-se nas categorias em que está interessado, especificar um idioma no qual receber as notificações e receber apenas notificações push para as categorias selecionadas nesse idioma.

Existem duas partes neste cenário:

  • A aplicação iOS permite que os dispositivos cliente especifiquem um idioma e subscrevam diferentes categorias de notícias de última hora;
  • O back-end transmite as notificações com a etiqueta e as funcionalidades de modelo dos Hubs de Notificação do Azure.

Neste tutorial, siga os seguintes passos:

  • Atualizar a interface de utilizador da aplicação
  • Criar a aplicação iOS
  • Enviar notificações de modelo localizadas a partir da aplicação de consola .NET
  • Enviar notificações de modelo localizadas a partir do dispositivo

Descrição Geral

Em Utilizar Hubs de Notificação para enviar notícias de última hora, criou uma aplicação que utilizou etiquetas para subscrever notificações para diferentes categorias de notícias. No entanto, muitas aplicações visam vários mercados e exigem a localização. Significa que o conteúdo das próprias notificações tem de ser localizado e entregue no conjunto correto de dispositivos. Este tutorial mostra-lhe como utilizar a funcionalidade de modelo dos Hubs de Notificação para entregar facilmente notificações de notícias de última hora localizadas.

Nota

Uma forma de enviar notificações localizadas é criar várias versões de cada etiqueta. Por exemplo, para suportar inglês, francês e mandarim, precisaria de três etiquetas diferentes para notícias mundiais: "world_en", "world_fr" e "world_ch". Em seguida, teria de enviar uma versão localizada das notícias mundiais para cada uma destas etiquetas. Neste tópico, vai utilizar modelos para evitar a proliferação de etiquetas e o requisito de envio de várias mensagens.

Os modelos são uma forma de especificar como um dispositivo específico deve receber uma notificação. O modelo especifica o formato de payload exato ao consultar as propriedades que fazem parte da mensagem enviada pelo back-end da sua aplicação. No seu caso, envia uma mensagem locale-agnóstica que contém todos os idiomas suportados:

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

Em seguida, certifique-se de que os dispositivos se registam com um modelo que se refere à propriedade correta. Por exemplo, uma aplicação iOS que quer registar-se em registos de notícias franceses com a seguinte sintaxe:

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

Para obter mais informações sobre modelos, veja o artigo Modelos .

Pré-requisitos

Atualizar a interface de utilizador da aplicação

Nesta secção, vai modificar a aplicação Notícias de Última Hora que criou no tópico Utilizar Hubs de Notificação para enviar notícias de última hora para enviar notícias de última hora localizadas através de modelos.

No seu MainStoryboard_iPhone.storyboard, adicione um Controlo Segmentado com os três idiomas: inglês, francês e mandarim.

Criar o storyboard da IU do iOS

Em seguida, certifique-se de que adiciona um IBOutlet no viewController.h, conforme mostrado na imagem seguinte:

Criar tomadas para os comutadores

Criar a aplicação iOS

  1. No seu Notification.h, adicione o retrieveLocale método e modifique os métodos de armazenamento e subscrição, conforme mostrado no seguinte 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;
    

    No seu Notification.m, modifique o storeCategoriesAndSubscribe método ao adicionar o locale parâmetro e armazená-lo nas predefinições do utilizador:

    - (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];
    }
    

    Em seguida, modifique o método de subscrição para incluir a região:

    - (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];
    }
    

    Utiliza o método registerTemplateWithDeviceToken, em vez de registerNativeWithDeviceToken. Quando se inscreve num modelo, tem de fornecer o modelo json e também um nome para o modelo (uma vez que a aplicação poderá querer registar modelos diferentes). Certifique-se de que regista as suas categorias como etiquetas, uma vez que pretende certificar-se de que recebe as notificações dessas notícias.

    Adicione um método para obter a região a partir das predefinições do utilizador:

    - (int) retrieveLocale {
        NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
    
        int locale = [defaults integerForKey:@"BreakingNewsLocale"];
    
        return locale < 0?0:locale;
    }
    
  2. Agora que modificou a Notifications classe, tem de se certificar de que utiliza ViewController o novo UISegmentControl. Adicione a seguinte linha no viewDidLoad método para se certificar de que mostra a região que está atualmente selecionada:

    self.Locale.selectedSegmentIndex = [notifications retrieveLocale];
    

    Em seguida, no seu subscribe método, altere a chamada para o storeCategoriesAndSubscribe seguinte código:

    [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. Por fim, tem de atualizar o didRegisterForRemoteNotificationsWithDeviceToken método na appDelegate.m, para que possa atualizar corretamente o seu registo quando a sua aplicação for iniciada. Altere a chamada para o subscribe método de notificações com o seguinte código:

    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) Enviar notificações de modelo localizadas a partir da aplicação de consola .NET

Quando envia notificações de modelo, só precisa de fornecer um conjunto de propriedades. Neste cenário, o conjunto de propriedades contém a versão localizada das notícias atuais.

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

Enviar notificações com uma aplicação de consola C#

Esta secção mostra como enviar notificações com uma aplicação de consola. O código transmite notificações para dispositivos Windows Store e iOS. Modifique o método SendTemplateNotificationAsync na aplicação de consola que criou anteriormente com o seguinte código:

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

O método SendTemplateNotificationAsync fornece a notícia localizada a todos os seus dispositivos, independentemente da plataforma. O seu hub de notificação cria e entrega o payload nativo correto a todos os dispositivos subscritos a uma etiqueta específica.

Enviar notificação com Os Serviços Móveis

No seu agendador de Serviços Móveis, utilize o seguinte script:

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 notificações de modelo localizadas a partir do dispositivo

Se não tiver acesso ao Visual Studio ou quiser apenas testar o envio das notificações do modelo localizado diretamente a partir da aplicação no dispositivo. Pode adicionar os parâmetros de modelo localizados ao SendNotificationRESTAPI método que definiu no 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];
}

Passos seguintes

Neste tutorial, enviou notificações localizadas para dispositivos iOS. Para saber como enviar notificações push para utilizadores específicos de aplicações iOS, avance para o seguinte tutorial: