次の方法で共有


チュートリアル: Azure Notification Hubs を使用して、ローカライズしたプッシュ通知を iOS に送信する

このチュートリアルでは、Azure Notification Hubs のテンプレート機能を使用して、言語およびデバイスごとにローカライズされたニュース速報通知をブロードキャストする方法を示します。 このチュートリアルでは、「Notification Hubs を使用したニュース速報の送信」で作成された iOS アプリから始めます。 完了すると、関心のあるカテゴリに登録したり、通知を受信する言語を指定したり、選択されたカテゴリのその言語のプッシュ通知のみを受信したりできます。

このシナリオは次の 2 つに分けられます。

  • iOS アプリケーションで、クライアント デバイスが言語を指定し、さまざまなニュース速報カテゴリを購読できるようになります。
  • バックエンドは、Azure Notification Hubs のタグおよびテンプレート機能を使用して通知をブロードキャストします。

このチュートリアルでは、次の手順を実行します。

  • アプリのユーザー インターフェイスを更新する
  • iOS アプリを構築する
  • .NET コンソール アプリからローカライズしたテンプレート通知を送信する
  • デバイスからローカライズしたテンプレート通知を送信する

概要

Notification Hubs を使用したニュース速報の送信」では、タグを使用してさまざまなニュース カテゴリの通知にサブスクライブするアプリを構築しました。 しかし、多くのアプリケーションは複数の市場をターゲットとしており、ローカライズが必要です。 つまり、通知自体の内容をローカライズし、適切な一連のデバイスに配信する必要があります。 このチュートリアルでは、Notification Hubs のテンプレート機能を使用して、ローカライズしたニュース速報通知を簡単に配信する方法を示します。

注意

ローカライズした通知を送信する方法の 1 つに、各タグの複数のバージョンを作成する方法があります。 たとえば、英語、フランス語、および標準中国語をサポートするには、世界のニュースに関して "world_en"、"world_fr"、"world_ch" の 3 種類のタグが必要になります。 次に、これらの各タグに世界のニュースのローカライズ版を送信する必要があります。 このトピックでは、テンプレートを使用してタグの急増を回避したり、複数のメッセージを送信しなくても済むようにしたりします。

テンプレートとは、特定のデバイスが通知をどのように受信するかを指定するための手段です。 テンプレートは、アプリケーション バックエンドにより送信されるメッセージの一部となっているプロパティを参照することで、正確なペイロードを指定します。 このケースでは、サポートされるすべての言語を含む、ロケールにとらわれないメッセージを送信します。

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

次に、各デバイスが確実に、適切なプロパティを参照するテンプレートに登録するようにします。 たとえば、フランス語のニュースに登録しようとする iOS アプリでは、次の構文を使用して登録します。

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

テンプレートの詳細については、「テンプレート」の記事を参照してください。

前提条件

  • このチュートリアルは「特定の iOS デバイスにプッシュ通知を送信する」のチュートリアルのコードに直接基づいて構築されているため、このチュートリアルを完了し、そのコードを使用可能にしてください。
  • Visual Studio 2019 はオプションです。

アプリのユーザー インターフェイスを更新する

このセクションでは、ローカライズしたニュース速報をテンプレートを使用して送信するために、トピック「Notification Hubs を使用したニュース速報の送信」で作成したニュース速報アプリを変更します。

MainStoryboard_iPhone.storyboard で、英語、フランス語、標準中国語の 3 つの言語を含む Segmented Control を追加します。

iOS UI のストーリーボードの作成

次に、次の図に示すように、ViewController.h で IBOutlet を確実に追加します。

スイッチのアウトレットを作成する

iOS アプリを構築する

  1. Notification.h で、retrieveLocale メソッドを追加し、次のコードに示すように store および subscribe メソッドを変更します。

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

    registerNativeWithDeviceToken の代わりに registerTemplateWithDeviceToken メソッドを使用します。 テンプレートを登録するときは、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 メソッドは、ニュースのローカライズされた部分を、プラットフォームに関係なく、すべてのデバイスに配信します。 通知ハブは、正しいネイティブ ペイロードをビルドし、それを特定のタグにサブスクライブされているすべてのデバイスに配信します。

Mobile Services を使用した通知の送信

Mobile Services スケジューラで、次のスクリプトを使用します。

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 アプリの特定のユーザーにプッシュ通知を送信する方法を学習するには、次のチュートリアルに進んでください。