共用方式為


教學課程:使用 Azure 通知中樞將當地語系化的推播通知傳送至 iOS

本教學課程說明如何使用 Azure 通知中樞的範本功能,廣播已依語言及裝置進行當地語系化的即時新聞通知。 在本教學課程中,您必須以在使用通知中樞傳送即時新聞中所建立 iOS 應用程式為基礎。 完成之後,您將可以註冊自己感興趣的類別、指定要以哪種語言接收通知,並且僅以該語言接收所選取類別的推播通知。

此場景有兩個部分:

  • iOS 應用程式允許用戶端裝置指定語言,以及訂閱不同的即時新聞類別;
  • 後端會使用 Azure 通知中樞的標記範本功能來廣播通知。

在本教學課程中,您會執行下列步驟:

  • 更新應用程式使用者介面
  • 建置 iOS 應用程式
  • 從 .NET 主控台應用程式傳送當地語系化的範本通知
  • 從裝置傳送當地語系化的範本通知

概觀

使用通知中樞傳送即時新聞中,您已建置使用標記來訂閱不同即時新聞類別通知的應用程式。 但有許多應用程式是以多個市場為目標的,因此需要當地語系化。 這表示通知本身的內容必須進行當地語系化,並傳遞至正確的裝置集。 本教學課程會說明如何使用通知中樞的範本功能,輕鬆地傳遞已當地語系化的即時新聞通知。

注意

傳送當地語系化通知的其中一個方法,是為每個標記建立多個版本。 例如,若要支援英文、法文和中文,您必須為世界新聞建立三個不同的標記:"world_en"、"world_fr" 和 "world_ch"。 接著,您必須將世界新聞的當地語系化版本分別傳送至這三個標記。 在本主題中,您會使用範本來避免使用過多的標籤和傳送過多訊息。

範本是指定特定裝置如何接收通知的方式之一。 範本可參照您的應用程式後端所傳送的訊息中包含的屬性,藉以指定確切的裝載格式。 在您的案例中,您會傳送地區設定無從驗證且包含所有支援語言的訊息:

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

接著,您會確保裝置會註冊至能參照正確屬性的範本。 例如,想要註冊法文新聞的 iOS 應用程式會使用下列語法進行註冊:

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

如需範本的詳細資訊,請參閱範本一文。

必要條件

更新應用程式使用者介面

在本節中,您會修改在使用通知中樞傳送即時新聞主題中所建立的即時新聞應用程式,以使用範本來傳送當地語系化的即時新聞。

在您的 MainStoryboard_iPhone.storyboard 中,新增具有三種語言的區段控制:英文、法文與中文。

Creating the iOS UI storyboard

接著,請確實在您的 ViewController.h 中新增 IBOutlet,如下圖所示:

Create outlets for the switches

建置 iOS 應用程式

  1. 在您的 Notification.h 中新增 retrieveLocale 方法,然後修改儲存和訂閱方法,如下列程式碼所示:

    - (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 方法:

    - (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 方法,以加入地區設定:

    - (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,而不是 registerNativeWithDeviceToken。 您在註冊範本時必須提供 json 範本,以及範本的名稱 (因為應用程式可能會註冊不同的範本)。 請確實將您的類別註冊為標籤,因為要確保能夠收到這些新聞的通知。

    加入方法,從使用者預設設定擷取地區設定:

    - (int) retrieveLocale {
        NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
    
        int locale = [defaults integerForKey:@"BreakingNewsLocale"];
    
        return locale < 0?0:locale;
    }
    
  2. 在已修改 Notifications 類別之後,您必須確保 ViewController 會使用新的 UISegmentControl。 請在 viewDidLoad 方法中新增下列程式碼行,以確實顯示目前選取的地區設定:

    self.Locale.selectedSegmentIndex = [notifications retrieveLocale];
    

    接著,在 subscribe 方法中,將您對 storeCategoriesAndSubscribe 的呼叫變更為下列程式碼:

    [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 方法,以便能在應用程式啟動時正確重新整理您的註冊。 使用下列程式碼,針對通知的 subscribe 方法,變更您的方法呼叫:

    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 主控台應用程式傳送當地語系化的範本通知

當您傳送範本通知時,您只需要提供一組屬性。 在此案例中,這組屬性包含已針對目前新聞進行當地語系化的版本。

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

使用 C# 主控台應用程式傳送通知

本節將使用主控台應用程式示範傳送通知的方式。 程式碼會將通知廣播到 Windows 市集和 iOS 裝置。 在您先前建立的主控台應用程式中,使用下列程式碼修改 SendTemplateNotificationAsync 方法:

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

SendTemplateNotificationAsync 方法會將已當地語系化的新聞片段傳遞至所有裝置,無論其平台為何。 通知中樞會建置並傳遞正確的原生承載給訂閱特定標記的所有裝置。

使用行動服務傳送通知

在行動服務排程器中,使用下列指令碼:

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

(選擇性) 從裝置傳送當地語系化的範本通知

如果您無法存取 Visual Studio,或只想要測試直接從裝置上的應用程式,請傳送當地語系化的範本通知。 您可以對在先前教學課程中所定義的 SendNotificationRESTAPI 方法,加入當地語系化的範本參數。

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

下一步

在本教學課程中,您已將當地語系化通知傳送至 iOS 裝置。 若要了解如何將通知推送至 iOS 應用程式的特定使用者,請繼續進行下列教學課程: