Esercitazione: Inviare notifiche push localizzate a iOS usando Hub di notifica di Azure

In questa esercitazione viene illustrato come usare la funzionalità relativa ai modelli di Hub di notifica di Azure per trasmettere notifiche relative alle ultime notizie localizzate in base alla lingua e al dispositivo. In questa esercitazione si inizia con l'app iOS creata in Usare hub di notifica per inviare notizie di rilievo. Al termine, è possibile registrarsi per le categorie interessate, specificare una lingua in cui ricevere le notifiche e ricevere solo notifiche push per le categorie selezionate in tale lingua.

Lo scenario è composto da due parti:

  • l'app per iOS consente ai dispositivi client di specificare una lingua e di sottoscrivere categorie diverse di ultime notizie;
  • il back-end trasmette le notifiche usando le funzionalità relative ai tag e ai modelli di Hub di notifica di Azure.

In questa esercitazione vengono completati i passaggi seguenti:

  • Aggiornare l'interfaccia utente dell'app
  • Compilare l'app iOS
  • Inviare notifiche modello localizzate dall'app console .NET
  • Inviare notifiche modello localizzate dal dispositivo

Panoramica

In Usare Hub di notifica per inviare notizie di rilievo, è stata creata un'app che ha usato tag per sottoscrivere notifiche per categorie di notizie diverse. Molte app, tuttavia, sono destinate a più mercati ed è necessario localizzarle. Questo significa che il contenuto delle notifiche stesse deve essere localizzato e inviato al set di dispositivi corretto. In questa esercitazione viene usata la funzionalità relativa ai modelli di Hub di notifica per inviare facilmente notifiche relative alle ultime notizie localizzate.

Nota

Un possibile modo per inviare notifiche localizzate consiste nel creare più versioni di ogni tag. Per supportare l'inglese, il francese e il mandarino, ad esempio, sono necessari tre tag diversi per le ultime notizie internazionali: "world_en", "world_fr" e "world_ch". È quindi necessario inviare una versione localizzata delle ultime notizie internazionali a ogni tag. In questo argomento verranno usati i modelli per evitare la proliferazione di tag e la necessità di inviare più messaggi.

I modelli sono un modo per specificare il modo in cui un dispositivo specifico deve ricevere una notifica. Il modello definisce lo specifico formato di payload da utilizzare, facendo riferimento alle proprietà del messaggio inviato dal back-end dell'app. In questo caso verrà inviato un messaggio indipendente dalle impostazioni locali, che contiene tutte le lingue supportate:

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

Si procede quindi a verificare che i dispositivi effettuino la registrazione con un modello che faccia riferimento alla proprietà corretta. Ad esempio, un'app iOS che vuole registrare per i registri di notizie francesi usando la sintassi seguente:

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

Per altre informazioni sui modelli, vedere l'articolo Modelli.

Prerequisiti

Aggiornare l'interfaccia utente dell'app

In questa sezione l'app Breaking News creata nell'argomento Utilizzo di Hub di notifica per inviare le ultime notizie viene modificata in modo da inviare notizie localizzate mediante modelli.

MainStoryboard_iPhone.storyboardIn , aggiungere un controllo segmentato con le tre lingue: inglese, francese e mandarino.

Creazione di storyboard dell'interfaccia utente iOS

Assicurarsi quindi di aggiungere un elemento IBOutlet in ViewController.h come illustrato nell'immagine seguente:

Creare outlet per le opzioni

Compilare l'app iOS

  1. Notification.hNel metodo aggiungere il metodo e modificare i retrieveLocale metodi di archiviazione e sottoscrizione, come illustrato nel codice seguente:

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

    In Notification.m modificare il metodo storeCategoriesAndSubscribe aggiungendo il parametro locale e archiviandolo nelle impostazioni utente predefinite:

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

    Modificare quindi il metodo subscribe in modo da includere le impostazioni locali:

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

    Si usa il metodo registerTemplateWithDeviceToken, invece di registerNativeWithDeviceToken. Quando si effettua la registrazione per un modello, è necessario fornire il modello json e un nome per il modello. Questo perché l'app potrebbe richiedere la registrazione di modelli diversi. Assicurarsi di registrare le categorie come tag, perché è necessario ricevere notifiche per le notizie.

    Aggiungere un metodo per recuperare le impostazioni locali dalle impostazioni predefinite dell'utente:

    - (int) retrieveLocale {
        NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
    
        int locale = [defaults integerForKey:@"BreakingNewsLocale"];
    
        return locale < 0?0:locale;
    }
    
  2. Dopo aver modificato la classe Notifications, è necessario verificare che ViewController usi il nuovo UISegmentControl. Aggiungere la riga seguente nel metodo viewDidLoad per assicurarsi che vengano mostrate le impostazioni locali attualmente selezionate:

    self.Locale.selectedSegmentIndex = [notifications retrieveLocale];
    

    Nel metodo subscribe sostituire quindi la chiamata a storeCategoriesAndSubscribe con il codice seguente:

    [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. Aggiornare infine il metodo didRegisterForRemoteNotificationsWithDeviceToken in AppDelegate.m, per poter aggiornare correttamente la registrazione all'avvio dell'applicazione. Modificare la chiamata al metodo subscribe delle notifiche con il codice seguente:

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

(facoltativo) Invio di notifiche modello localizzato dall'app console .NET

Quando si inviano notifiche modello, è necessario fornire solo un set di proprietà. In questo scenario il set di proprietà contiene la versione localizzata delle notizie correnti.

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

Inviare notifiche tramite un'app console C#

Questa sezione illustra come inviare notifiche tramite un'app console. Il codice trasmette le notifiche ai dispositivi iOS e Windows Store. Modificare il metodo SendTemplateNotificationAsync nell'app console creata in precedenza con il codice seguente:

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

Il metodo SendTemplateNotificationAsync distribuisce la notizia localizzata a tutti i dispositivi, indipendentemente dalla piattaforma. L'hub di notifica crea il payload nativo corretto e lo distribuisce a tutti i dispositivi che hanno sottoscritto un tag specifico.

Invio della notifica con Servizi mobili

Nell'utilità di pianificazione di Servizi mobili usare lo script seguente:

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

(facoltativo) Invio di notifiche modello localizzato dal dispositivo

Se non si ha accesso a Visual Studio o si desidera solo l'invio di notifiche modello localizzato direttamente dall'app sul dispositivo. È possibile aggiungere i parametri di modello localizzato per il metodo SendNotificationRESTAPI definito nell'esercitazione precedente.

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

Passaggi successivi

In questa esercitazione le notifiche localizzate sono state inviate ai dispositivi iOS. Per informazioni sulle procedure per eseguire il push di notifiche a utenti specifici di app iOS, passare all'esercitazione seguente: