Tutorial: enviar notificações por push localizadas para dispositivos iOS usando Hubs de Notificação do Azure

Este tutorial mostra como usar o recurso modelos dos Hubs de Notificação do Azure para difundir notificações de últimas notícias que foram localizadas por idioma e dispositivo. Neste tutorial você começa com o aplicativo iOS criado em Usar Hubs de Notificação para enviar as últimas notícias. Ao concluir, você poderá se registrar nas categorias de seu interesse, especificar o idioma no qual deseja receber as notificações e receber notificações por push para as categorias selecionadas nesse idioma.

Há duas partes que compõem esse cenário:

  • o aplicativo iOS permite que dispositivos cliente especifiquem um idioma e se inscrevam em diferentes categorias de últimas notícias;
  • O back-end transmite as notificações usando os recursos tag e template dos Hubs de Notificação do Azure.

Neste tutorial, você deve executar as seguintes etapas:

  • Atualizar a interface do usuário do aplicativo
  • Compilar o aplicativo iOS
  • Enviar notificações de modelo localizado do aplicativo de console do .NET.
  • Enviar notificações de modelo localizado do dispositivo

Visão geral

Em Usar Hubs de Notificação para enviar as últimas notícias, você criou um aplicativo que usou marcas para assinar notificações de diferentes categorias de notícias. No entanto, muitos aplicativos são destinados a vários mercados e requerem localização. Isso significa que o conteúdo das notificações deve ser localizado e enviado para o conjunto de dispositivos correto. Este tutorial ensina a usar o recurso modelo dos Hubs de Notificação para enviar facilmente notificações de últimas notícias localizadas.

Observação

Uma maneira de enviar notificações localizadas é criar várias versões de cada marca. Por exemplo, para dar suporte a inglês, francês e mandarim, precisamos de três marcas diferentes para notícias do mundo: "world_en", "world_fr" e "world_ch". Em seguida, precisamos enviar uma versão localizada das notícias do mundo para cada uma dessas marcas. Neste tópico, use modelos para evitar a proliferação de marcas e a necessidade de enviar várias mensagens.

Os modelos são uma maneira de especificar como um dispositivo específico deve receber uma notificação. O modelo especifica o formato exato da carga referindo-se às propriedades que fazem parte da mensagem enviada por seu aplicativo de back-end. No seu caso, você enviará uma mensagem independente de localidade contendo todos os idiomas com suporte:

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

Em seguida, você verificará se os dispositivos se registram com um modelo que faz referência à propriedade correta. Por exemplo, um aplicativo iOS que deseja se registrar para receber notícias em francês registrará o seguinte:

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

Para saber mais sobre o uso de modelos, consulte o artigo Modelos.

Pré-requisitos

Atualizar a interface do usuário do aplicativo

Nesta seção, você modificará o aplicativo Últimas notícias que criou no tópico Usar Hubs de Notificação para enviar as últimas notícias a fim de enviar as últimas notícias localizadas usando modelos.

No seu MainStoryboard_iPhone.storyboard, adicione um Controle Segmentado em três idiomas: inglês, francês e mandarim.

Criar o storyboard de interface do usuário do iOS

Em seguida, adicione um IBOutlet em seu ViewController.h, conforme mostrado na seguinte imagem:

Criar saídas para os switches

Compilar o aplicativo iOS

  1. No seu Notification.h, adicione o retrieveLocale método e modifique os métodos armazenagem e assinatura, conforme mostrado no código a seguir:

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

    Em Notification.m, modifique o método storeCategoriesAndSubscribe adicionando o parâmetro locale e armazenando-o nos padrões do usuário:

    - (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 subscribe para incluir o locale:

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

    Use o método registerTemplateWithDeviceToken, em vez de registerNativeWithDeviceToken. Ao registrar um modelo, você deve fornecer o modelo json e também um nome para o modelo (uma vez que nosso aplicativo talvez queira registrar modelos diferentes). Registre suas categorias como marcas, para garantir o recebimento das notificações sobre essas notícias.

    Adicione um método para recuperar o locale das configurações padrão do usuário:

    - (int) retrieveLocale {
        NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
    
        int locale = [defaults integerForKey:@"BreakingNewsLocale"];
    
        return locale < 0?0:locale;
    }
    
  2. Agora que você modificou a classe Notifications, faça com que ViewController use o novo UISegmentControl. Adicione a seguinte linha ao método viewDidLoad para ter certeza de mostrar a localidade que está selecionada no momento:

    self.Locale.selectedSegmentIndex = [notifications retrieveLocale];
    

    Em seguida, no método subscribe, altere a chamada a storeCategoriesAndSubscribe para o 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, atualize o método didRegisterForRemoteNotificationsWithDeviceToken em AppDelegate.m, de forma que você possa atualizar corretamente seu registro quando o aplicativo iniciar. Altere a chamada ao método de notificações subscribe 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 do aplicativo de console do .NET.

Ao enviar notificações de modelo, será necessário somente fornecer um conjunto de propriedades. Nesse 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 usando um aplicativo do console C#

Esta seção mostra como enviar notificações usando um aplicativo do console. O código transmite notificações para o Microsoft Windows Store e dispositivos iOS. Modifique o método SendTemplateNotificationAsync no aplicativo de console que você criou anteriormente, com o código a seguir:

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 para todos os dispositivos, independentemente da plataforma. O hub de notificação compila e distribui a carga nativa correta para todos os dispositivos inscritos em uma marca específica.

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

No agendador de Serviços Móveis, use o script a seguir:

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) Envie notificações de modelo localizado do dispositivo

Se você não tem acesso ao Visual Studio ou deseja apenas testar o envio das notificações de modelo localizado diretamente do aplicativo no dispositivo. Você pode apenas adicionar os parâmetros de modelo localizado ao método SendNotificationRESTAPI definido 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];
}

Próximas etapas

Neste tutorial, você enviou notificações localizadas para dispositivos iOS. Para saber como enviar notificações por push para usuários de aplicativos iOS específicos, vá para o seguinte tutorial: