Поделиться через


Учебник. Отправка локализованных push-уведомлений на iOS с помощью Центров уведомлений Azure

В этом руководстве показано, как использовать функцию шаблонов службы "Центры уведомлений Azure" для рассылки уведомлений об экстренных новостях, локализованных для языка и устройства. В этом руководстве вы начнете с приложения iOS, созданного в руководстве Использование концентраторов уведомлений для передачи экстренных новостей. По завершении вы можете зарегистрироваться для категорий, которые вас интересуют, указать язык, на котором будут получать уведомления, и получать только push-уведомления для выбранных категорий на этом языке.

Этот сценарий состоит из двух частей:

  • приложение iOS позволяет клиентским устройствам указывать язык и подписываться на различные категории экстренных новостей;
  • сервер рассылает уведомления, используя функции тегов и шаблонов службы "Центры уведомлений Azure".

При работе с этим руководством вы выполните следующие задачи:

  • обновление пользовательского интерфейса приложения;
  • Выполнение сборки приложения iOS
  • отправка локализованных шаблонных уведомлений из консольного приложения .NET;
  • отправка локализованных шаблонных уведомлений с устройства.

Обзор

В руководстве Использование концентраторов уведомлений для передачи экстренных новостей вы создали приложение, которое использовало теги для подписки на уведомления для различных категорий новостей. Однако многие приложения ориентированы на несколько рынков и требуют локализации. Это означает, что само содержимое уведомлений должно быть локализовано и доставлено в правильный набор устройств. В этом руководстве демонстрируются способы использования шаблонов службы "Центры уведомлений", которые позволяют легко доставлять локализованные уведомления об экстренных новостях.

Примечание

Один из способов отправки локализованных уведомлений — создание нескольких версий каждого тега. Например, для поддержки английского, французского и китайского языков понадобится три разных тега для мировых новостей: world_en, world_fr и world_ch. Затем необходимо отправить локализованную версию мировых новостей по каждому из этих тегов. В этом разделе мы используем шаблоны во избежание избыточного количества тегов и необходимости отправки нескольких сообщений.

Шаблоны — это способ указать, как конкретное устройство должно получать уведомление. Шаблон указывает точный формат полезных данных путем обращения к свойствам, которые являются частью сообщения, отправленного сервером вашего приложение. В нашем случае отправляется независимое от языка сообщение, которое содержит все поддерживаемые языки.

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

Затем следует убедиться, что устройство зарегистрировано с использованием шаблона, который ссылается на нужное свойство. Например, приложение iOS, которое требуется зарегистрировать для французских новостей, использует следующую синтаксическую конструкцию для регистрации:

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

Дополнительные сведения о шаблонах см. в статье Шаблоны.

Предварительные требования

обновление пользовательского интерфейса приложения;

В этом разделе вы измените приложение Breaking News, созданное в разделе Использование концентраторов уведомлений для передачи экстренных новостей для отправки локализованных экстренных новостей с помощью шаблонов.

В вашем MainStoryboard_iPhone.storyboard добавьте сегментированный элемент управления с тремя языками: английский, французский и мандарин.

Создание раскадровки пользовательского интерфейса для iOS

Затем обязательно добавьте IBOutlet в свой файл ViewController.h, как показано на рисунке ниже.

Создание выходов для переключателей

Выполнение сборки приложения 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 измените метод storeCategoriesAndSubscribe путем добавления параметра locale и сохранения его в качестве пользователя по умолчанию.

    - (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. И наконец, необходимо обновить метод didRegisterForRemoteNotificationsWithDeviceToken в методе AppDelegate.m, чтобы правильно обновить регистрацию при запуске приложения. Замените вызов метода уведомлений 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. Чтобы узнать, как отправлять push-уведомления конкретным пользователям приложений iOS, перейдите к следующему руководству.