教學課程:了解如何使用 Azure 通知中樞將當地語系化通知推播至 iOS 裝置Tutorial: Push localized notifications to iOS devices using Azure Notification Hubs

本教學課程說明如何使用 Azure 通知中樞的範本功能,廣播已依語言及裝置進行當地語系化的即時新聞通知。This tutorial shows you how to use the templates feature of Azure Notification Hubs to broadcast breaking news notifications that have been localized by language and device. 在本教學課程中,您必須以在使用通知中樞傳送即時新聞中所建立 iOS 應用程式為基礎。In this tutorial, you start with the iOS app created in Use Notification Hubs to send breaking news. 完成時,您可以註冊您感興趣的類別、指定用來接收通知的語言,以及僅接收該語言中所選類別的推播通知。When complete, you can register for categories you're interested in, specify a language in which to receive the notifications, and receive only push notifications for the selected categories in that language.

此案例分成兩部分:There are two parts to this scenario:

  • iOS 應用程式允許用戶端裝置指定語言,以及訂閱不同的即時新聞類別;iOS app allows client devices to specify a language, and to subscribe to different breaking news categories;
  • 後端會使用 Azure 通知中樞的標記範本功能來廣播通知。The back-end broadcasts the notifications, using the tag and template features of Azure Notification Hubs.

在本教學課程中,您會執行下列步驟:In this tutorial, you take the following steps:

  • 更新應用程式使用者介面Update the app user interface
  • 建置 iOS 應用程式Build the iOS app
  • 從 .NET 主控台應用程式傳送當地語系化的範本通知Send localized template notifications from .NET console app
  • 從裝置傳送當地語系化的範本通知Send localized template notifications from the device

總覽Overview

使用通知中樞傳送即時新聞中,您已建置使用標記來訂閱不同即時新聞類別通知的應用程式。In Use Notification Hubs to send breaking news, you built an app that used tags to subscribe to notifications for different news categories. 但有許多應用程式是以多個市場為目標的,因此需要當地語系化。Many apps, however, target multiple markets and require localization. 這表示通知本身的內容必須進行當地語系化,並傳遞至正確的裝置集。It means that the content of the notifications themselves have to be localized and delivered to the correct set of devices. 本教學課程會說明如何使用通知中樞的範本功能,輕鬆地傳遞已當地語系化的即時新聞通知。This tutorial shows you how to use the template feature of Notification Hubs to easily deliver localized breaking news notifications.

注意

傳送當地語系化通知的其中一個方法,是為每個標記建立多個版本。One way to send localized notifications is to create multiple versions of each tag. 例如,若要支援英文、法文和中文,您必須為世界新聞建立三個不同的標記:"world_en"、"world_fr" 和 "world_ch"。For instance, to support English, French, and Mandarin, you would need three different tags for world news: "world_en", "world_fr", and "world_ch". 接著,您必須將世界新聞的當地語系化版本分別傳送至這三個標記。You would then have to send a localized version of the world news to each of these tags. 在本主題中,您會使用範本來避免使用過多的標籤和傳送過多訊息。In this topic, you use templates to avoid the proliferation of tags and the requirement of sending multiple messages.

範本是指定特定裝置應如何接收通知的方式。Templates are a way to specify how a specific device should receive a notification. 範本可參照您的應用程式後端所傳送的訊息中包含的屬性,藉以指定確切的裝載格式。The template specifies the exact payload format by referring to properties that are part of the message sent by your app back-end. 在您的案例中,您會傳送地區設定無從驗證且包含所有支援語言的訊息:In your case, you send a locale-agnostic message containing all supported languages:

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

接著,您會確保裝置會註冊至能參照正確屬性的範本。Then you ensure that devices register with a template that refers to the correct property. 例如,想要註冊法文新聞的 iOS 應用程式會使用下列語法進行註冊:For instance, an iOS app that wants to register for French news registers using the following syntax:

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

如需範本的詳細資訊,請參閱範本一文。For more information on templates, see Templates article.

必要條件Prerequisites

更新應用程式使用者介面Update the app user interface

在本節中,您會修改在使用通知中樞傳送即時新聞主題中所建立的即時新聞應用程式,以使用範本來傳送當地語系化的即時新聞。In this section, you modify the Breaking News app that you created in the topic Use Notification Hubs to send breaking news to send localized breaking news using templates.

在您的 MainStoryboard_iPhone.storyboard 中,新增三種語言的分段控制:英文、法文和中文。In your MainStoryboard_iPhone.storyboard, add a Segmented Control with the three languages: English, French, and Mandarin.

建立 iOS UI 分鏡腳本

接著,請確實在您的 ViewController.h 中新增 IBOutlet,如下圖所示:Then make sure to add an IBOutlet in your ViewController.h as shown in the following image:

建立參數的輸出

建置 iOS 應用程式Build the iOS app

  1. 在您Notification.h的中, retrieveLocale新增方法,並修改 store 和訂閱者法,如下列程式碼所示:In your Notification.h, add the retrieveLocale method, and modify the store and subscribe methods as shown in the following code:

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

    在您的 Notification.m 中新增 locale 參數,並將其儲存在使用者預設值中,以修改 storeCategoriesAndSubscribe 方法:In your Notification.m, modify the storeCategoriesAndSubscribe method, by adding the locale parameter and storing it in the user defaults:

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

    然後修改 subscribe 方法,以加入地區設定:Then modify the subscribe method to include the 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];
    }
    

    您應使用方法 registerTemplateWithDeviceToken,而不是 registerNativeWithDeviceTokenYou use the method registerTemplateWithDeviceToken, instead of registerNativeWithDeviceToken. 您在註冊範本時必須提供 json 範本,以及範本的名稱 (因為應用程式可能會註冊不同的範本)。When you register for a template, you have to provide the json template and also a name for the template (as the app might want to register different templates). 請確實將您的類別註冊為標籤,因為要確保能夠收到這些新聞的通知。Make sure to register your categories as tags, as you want to make sure to receive the notifications for those news.

    加入方法,從使用者預設設定擷取地區設定:Add a method to retrieve the locale from the user default settings:

    - (int) retrieveLocale {
        NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
    
        int locale = [defaults integerForKey:@"BreakingNewsLocale"];
    
        return locale < 0?0:locale;
    }
    
  2. 在已修改 Notifications 類別之後,您必須確保 ViewController 會使用新的 UISegmentControlNow that you modified the Notifications class, you have to make sure that the ViewController makes use of the new UISegmentControl. 請在 viewDidLoad 方法中新增下列程式碼行,以確實顯示目前選取的地區設定:Add the following line in the viewDidLoad method to make sure to show the locale that is currently selected:

    self.Locale.selectedSegmentIndex = [notifications retrieveLocale];
    

    接著,在 subscribe 方法中,將您對 storeCategoriesAndSubscribe 的呼叫變更為下列程式碼:Then, in your subscribe method, change your call to the storeCategoriesAndSubscribe to the following code:

    [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. 最後,您必須在 AppDelegate.m 中更新 didRegisterForRemoteNotificationsWithDeviceToken 方法,以便能在應用程式啟動時正確重新整理您的註冊。Finally, you have to update the didRegisterForRemoteNotificationsWithDeviceToken method in your AppDelegate.m, so that you can correctly refresh your registration when your app starts. 使用下列程式碼,針對通知的 subscribe 方法,變更您的方法呼叫:Change your call to the subscribe method of notifications with the following code:

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

(選擇性) 從.NET 主控台應用程式傳送當地語系化的範本通知(optional) Send localized template notifications from .NET console app

當您傳送範本通知時,您只需要提供一組屬性。When you send template notifications, you only need to provide a set of properties. 在此案例中,這組屬性包含已針對目前新聞進行當地語系化的版本。In this scenario, the set of properties contain the localized version of the current news.

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

使用 C# 主控台應用程式傳送通知Send notifications using a C# console app

本節將使用主控台應用程式示範傳送通知的方式。This section shows how to send notifications using a console app. 程式碼會將通知廣播到 Windows 市集和 iOS 裝置。The code broadcasts notifications to both Windows Store and iOS devices. 在您先前建立的主控台應用程式中,使用下列程式碼修改 SendTemplateNotificationAsync 方法:Modify the SendTemplateNotificationAsync method in the console app you previously created with the following code:

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

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

SendTemplateNotificationAsync 方法會將已當地語系化的新聞片段傳遞至所有裝置,無論其平台為何。The SendTemplateNotificationAsync method delivers the localized piece of news to all your devices, irrespective of the platform. 通知中樞會建置並傳遞正確的原生承載給訂閱特定標記的所有裝置。Your notification hub builds and delivers the correct native payload to all the devices subscribed to a specific tag.

使用行動服務傳送通知Sending notification with Mobile Services

在行動服務排程器中,使用下列指令碼:In your Mobile Services scheduler, use the following 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");
    }
});

(選擇性) 從裝置傳送當地語系化的範本通知(optional) Send localized template notifications from the device

如果您無法存取 Visual Studio,或只想要測試直接從裝置上的應用程式,請傳送當地語系化的範本通知。If you don't have access to Visual Studio, or want to just test sending the localized template notifications directly from the app on the device. 您可以對在先前教學課程中所定義的 SendNotificationRESTAPI 方法,加入當地語系化的範本參數。You can add the localized template parameters to the SendNotificationRESTAPI method you defined in the previous tutorial.

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

後續步驟Next steps

在本教學課程中,您已將當地語系化通知傳送至 iOS 裝置。In this tutorial, you sent localized notifications to iOS devices. 若要了解如何將通知推送至 iOS 應用程式的特定使用者,請繼續進行下列教學課程:To learn how to push notifications to specific users of iOS apps, advance to the following tutorial: