Руководство. Отправка push-уведомлений на определенные устройства iOS с помощью Центров уведомлений Azure
Обзор
В этом руководстве показано, как использовать Центры уведомлений Azure для трансляции уведомлений о критических новостях в приложение iOS. По завершении вы можете зарегистрироваться для категорий критических новостей, которые вас интересуют, и получать только push-уведомления для этих категорий. Этот сценарий является общим шаблоном для многих приложений, где уведомления должны отправляться группам пользователей, которые ранее объявили им интерес, например RSS-читатель, приложения для музыкальных поклонников и т. д.
Сценарии трансляции включены путем включения одного или нескольких тегов при создании регистрации в центре уведомлений. Когда уведомления отправляются в тег, устройства, зарегистрированные для тега, получают уведомление. Так как теги являются просто строками, они не должны быть подготовлены заранее. Дополнительные сведения о тегах см. в статье "Маршрутизация и выражения тегов центров уведомлений".
При работе с этим руководством вы выполните следующие задачи:
- Добавление выбора категории в приложение
- Отправка помеченных уведомлений
- Отправка уведомлений с устройства
- Запуск приложения и создание уведомлений
Предпосылки
В этом разделе предстоит продолжить разработку приложения, созданного по Руководству: Push-уведомления в iOS-приложения с помощью Azure Notification Hubs. Перед началом работы с этим руководством необходимо выполнить инструкции по отправке push-уведомлений в приложения iOS с помощью Центров уведомлений Azure.
Добавление выбора категории в приложение
Первым шагом является добавление элементов пользовательского интерфейса в существующую раскадровку, которая позволяет пользователю выбирать категории, чтобы зарегистрироваться. Категории, выбранные пользователем, хранятся на устройстве. При запуске приложения в центре уведомлений создается регистрация устройства с выбранными категориями в виде тегов.
В MainStoryboard_iPhone.storyboard добавьте следующие компоненты из библиотеки объектов:
Метка с текстом "Критические новости",
Метки с текстами категорий "Мир", "Политика", "Бизнес", "Технология", "Наука", "Спорт",
По одному переключателю на каждую категорию, задайте состояние каждого переключателя на Выключено по умолчанию.
Одна кнопка с меткой "Подписаться"
Раскадровка должна выглядеть следующим образом:
В редакторе помощника создайте выходы для всех переключателей и назовите их "WorldSwitch", "PoliticsSwitch", "BusinessSwitch", "TechnologySwitch", "ScienceSwitch", "SportsSwitch".
Создайте действие для вашей кнопки под названием
subscribe
;ViewController.h
должен содержать следующий код:@property (weak, nonatomic) IBOutlet UISwitch *WorldSwitch; @property (weak, nonatomic) IBOutlet UISwitch *PoliticsSwitch; @property (weak, nonatomic) IBOutlet UISwitch *BusinessSwitch; @property (weak, nonatomic) IBOutlet UISwitch *TechnologySwitch; @property (weak, nonatomic) IBOutlet UISwitch *ScienceSwitch; @property (weak, nonatomic) IBOutlet UISwitch *SportsSwitch; - (IBAction)subscribe:(id)sender;
Создайте новый Cocoa Touch класс под названием
Notifications
. Скопируйте следующий код в разделе интерфейса файла Notifications.h:@property NSData* deviceToken; - (id)initWithConnectionString:(NSString*)listenConnectionString HubName:(NSString*)hubName; - (void)storeCategoriesAndSubscribeWithCategories:(NSArray*)categories completion:(void (^)(NSError* error))completion; - (NSSet*)retrieveCategories; - (void)subscribeWithCategories:(NSSet*)categories completion:(void (^)(NSError *))completion;
Добавьте следующую директиву импорта в Notifications.m:
#import <WindowsAzureMessaging/WindowsAzureMessaging.h>
Скопируйте следующий код в разделе реализации файла Notifications.m.
SBNotificationHub* hub; - (id)initWithConnectionString:(NSString*)listenConnectionString HubName:(NSString*)hubName{ hub = [[SBNotificationHub alloc] initWithConnectionString:listenConnectionString notificationHubPath:hubName]; return self; } - (void)storeCategoriesAndSubscribeWithCategories:(NSSet *)categories completion:(void (^)(NSError *))completion { NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; [defaults setValue:[categories allObjects] forKey:@"BreakingNewsCategories"]; [self subscribeWithCategories:categories completion:completion]; } - (NSSet*)retrieveCategories { NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults]; NSArray* categories = [defaults stringArrayForKey:@"BreakingNewsCategories"]; if (!categories) return [[NSSet alloc] init]; return [[NSSet alloc] initWithArray:categories]; } - (void)subscribeWithCategories:(NSSet *)categories completion:(void (^)(NSError *))completion { NSString* templateBodyAPNS = @"{\"aps\":{\"alert\":\"$(messageParam)\"}}"; [hub registerTemplateWithDeviceToken:self.deviceToken name:@"simpleAPNSTemplate" jsonBodyTemplate:templateBodyAPNS expiryTemplate:@"0" tags:categories completion:completion]; }
Этот класс использует локальное хранилище для хранения и получения категорий новостей, получаемых этим устройством. Кроме того, он содержит метод регистрации для этих категорий с помощью регистрации шаблона .
В файле
AppDelegate.h
добавьте оператор импорта дляNotifications.h
и добавьте свойство для экземпляра классаNotifications
.#import "Notifications.h" @property (nonatomic) Notifications* notifications;
В методе
didFinishLaunchingWithOptions
вAppDelegate.m
добавьте код для инициализации экземпляра уведомлений в начале метода.
HUBNAME
иHUBLISTENACCESS
(определены вhubinfo.h
) должны были уже быть заменены заполнителями именем концентратора уведомлений<hub name>
и строкой подключения<connection string with listen access>
для DefaultListenSharedAccessSignature, полученной ранее.self.notifications = [[Notifications alloc] initWithConnectionString:HUBLISTENACCESS HubName:HUBNAME];
Примечание.
Поскольку учетные данные, поставляемые с клиентским приложением, обычно не защищены, следует распространять ключ только для доступа к прослушиванию с клиентским приложением. Доступ на прослушивание позволяет приложению регистрировать уведомления, но существующие регистрации не могут быть изменены и уведомления не могут быть отправлены. Полный ключ доступа используется в защищенной серверной службе для отправки уведомлений и изменения существующих регистраций.
В методе
didRegisterForRemoteNotificationsWithDeviceToken
замените код в методеAppDelegate.m
следующим кодом, чтобы передать маркерnotifications
устройства в класс. Классnotifications
выполняет регистрацию для уведомлений с категориями. Если пользователь изменяет выбранные категории, вызовитеsubscribeWithCategories
метод в ответ на кнопку подписки , чтобы обновить их.Примечание.
Так как маркер устройства, назначенный службой push-уведомлений Apple (APNS), может изменяться в любое время, следует часто регистрировать уведомления, чтобы избежать сбоев уведомлений. В этом примере регистрируется получение уведомлений каждый раз при запуске приложения. Для приложений, которые выполняются часто, более одного раза в день, можно пропустить регистрацию, чтобы сохранить пропускную способность, если с момента предыдущей регистрации прошло менее одного дня.
self.notifications.deviceToken = deviceToken; // Retrieves the categories from local storage and requests a registration for these categories // each time the app starts and performs a registration. NSSet* categories = [self.notifications retrieveCategories]; [self.notifications subscribeWithCategories:categories completion:^(NSError* error) { if (error != nil) { NSLog(@"Error registering for notifications: %@", error); } }];
На этом этапе в методе не должно быть другого кода
didRegisterForRemoteNotificationsWithDeviceToken
.Следующие методы уже должны присутствовать в
AppDelegate.m
из завершения руководства Начало работы с Центрами уведомлений. В противном случае добавьте их.- (void)MessageBox:(NSString *)title message:(NSString *)messageText { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title message:messageText delegate:self cancelButtonTitle:@"OK" otherButtonTitles: nil]; [alert show]; } - (void)application:(UIApplication *)application didReceiveRemoteNotification: (NSDictionary *)userInfo { NSLog(@"%@", userInfo); [self MessageBox:@"Notification" message:[[userInfo objectForKey:@"aps"] valueForKey:@"alert"]]; }
Этот метод обрабатывает уведомления, полученные при запуске приложения, отображая простой UIAlert.
В
ViewController.m
добавьте инструкцию дляAppDelegate.h
, а затем скопируйте следующий код в методsubscribe
, созданный Xcode. Этот код обновляет регистрацию уведомлений, чтобы использовать новые теги категорий, выбранные пользователем в пользовательском интерфейсе.#import "Notifications.h" NSMutableArray* categories = [[NSMutableArray alloc] init]; if (self.WorldSwitch.isOn) [categories addObject:@"World"]; if (self.PoliticsSwitch.isOn) [categories addObject:@"Politics"]; if (self.BusinessSwitch.isOn) [categories addObject:@"Business"]; if (self.TechnologySwitch.isOn) [categories addObject:@"Technology"]; if (self.ScienceSwitch.isOn) [categories addObject:@"Science"]; if (self.SportsSwitch.isOn) [categories addObject:@"Sports"]; Notifications* notifications = [(AppDelegate*)[[UIApplication sharedApplication]delegate] notifications]; [notifications storeCategoriesAndSubscribeWithCategories:categories completion: ^(NSError* error) { if (!error) { UIAlertView *alert = [[UIAlertView alloc] initWithTitle:"Notification" message:"Subscribed" delegate:self cancelButtonTitle:@"OK" otherButtonTitles: nil]; [alert show]; } else { NSLog(@"Error subscribing: %@", error); } }];
Этот метод создает
NSMutableArray
категории и используетNotifications
класс для хранения списка в локальном хранилище и регистрирует соответствующие теги в центре уведомлений. При изменении категорий регистрация создается заново с новыми категориями.В
ViewController.m
добавьте следующий код в методviewDidLoad
, чтобы задать пользовательский интерфейс на основе ранее сохраненных категорий.// This updates the UI on startup based on the status of previously saved categories. Notifications* notifications = [(AppDelegate*)[[UIApplication sharedApplication]delegate] notifications]; NSSet* categories = [notifications retrieveCategories]; if ([categories containsObject:@"World"]) self.WorldSwitch.on = true; if ([categories containsObject:@"Politics"]) self.PoliticsSwitch.on = true; if ([categories containsObject:@"Business"]) self.BusinessSwitch.on = true; if ([categories containsObject:@"Technology"]) self.TechnologySwitch.on = true; if ([categories containsObject:@"Science"]) self.ScienceSwitch.on = true; if ([categories containsObject:@"Sports"]) self.SportsSwitch.on = true;
Теперь приложение может хранить набор категорий в локальном хранилище устройства, используемом для регистрации в центре уведомлений при запуске приложения. Пользователь может изменить выбор категорий во время выполнения и вызвать метод subscribe
, чтобы обновить данные регистрации устройства. Затем вы обновите приложение, чтобы отправить уведомления о критических новостях непосредственно в самом приложении.
(необязательно) Отправка помеченных уведомлений
Если у вас нет доступа к Visual Studio, вы можете перейти к следующему разделу и отправить уведомления из самого приложения. Вы также можете отправить соответствующее уведомление шаблона на портале Azure с помощью вкладки отладки для центра уведомлений.
В этом разделе вы отправляете срочные новости как уведомления с тегами из консольного приложения .NET.
В Visual Studio создайте консольное приложение Visual C#:
- В меню выберите "Файл>нового>проекта".
- В разделе "Создание проекта" выберите консольное приложение (.NET Framework) для C# в списке шаблонов и нажмите кнопку "Далее".
- Введите название приложения.
- Для решения выберите "Добавить в решение" и нажмите кнопку "Создать ", чтобы создать проект.
\Выберите Сервис\\>\Диспетчер пакетов NuGet\\>\Консоль диспетчера пакетов\, а затем в окне консоли выполните следующую команду:
Install-Package Microsoft.Azure.NotificationHubs
Это действие добавляет ссылку на SDK Azure Notification Hubs, используя пакет Microsoft.Azure.NotificationHubs.
Откройте файл Program.cs и добавьте следующую
using
инструкцию:using Microsoft.Azure.NotificationHubs;
Program
В классе добавьте следующий метод или замените его, если оно уже существует: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"}}; // Create an array of breaking news categories. var categories = new string[] { "World", "Politics", "Business", "Technology", "Science", "Sports"}; // Send the notification as a template notification. All template registrations that contain // "messageParam" and the proper tags will receive the notifications. // This includes APNS, GCM/FCM, WNS, and MPNS template registrations. Dictionary<string, string> templateParams = new Dictionary<string, string>(); foreach (var category in categories) { templateParams["messageParam"] = "Breaking " + category + " News!"; await hub.SendTemplateNotificationAsync(templateParams, category); } }
Этот код отправляет уведомление шаблона для каждого из шести тегов в массиве строк. Использование тегов гарантирует, что устройства получают уведомления только для зарегистрированных категорий.
В приведенном выше коде замените заполнители
<hub name>
и<connection string with full access>
именем центра уведомлений и строкой подключения для DefaultFullSharedAccessSignature на панели вашего центра уведомлений.В методе
Main()
добавьте следующие строки:SendTemplateNotificationAsync(); Console.ReadLine();
Создайте консольное приложение.
(необязательно) Отправка уведомлений с устройства
Обычно уведомления отправляются серверной службой, но вы можете отправлять уведомления о критических новостях непосредственно из приложения. Для этого обновите метод, определенный SendNotificationRESTAPI
в руководстве по началу работы с Центрами уведомлений .
В
ViewController.m
, обновите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 : %@\"}", categoryTag, self.notificationMessage.text]; // 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]; }
В
ViewController.m
обновите действиеSend Notification
, как показано в коде ниже. Таким образом, он отправляет уведомления, используя каждый тег по отдельности, и отправляет их на несколько платформ.- (IBAction)SendNotificationMessage:(id)sender { self.sendResults.text = @""; NSArray* categories = [NSArray arrayWithObjects: @"World", @"Politics", @"Business", @"Technology", @"Science", @"Sports", nil]; // Lets send the message as breaking news for each category to WNS, FCM, and APNS // using a template. for(NSString* category in categories) { [self SendNotificationRESTAPI:category]; } }
Перестройте проект и убедитесь, что у вас нет ошибок сборки.
Запуск приложения и создание уведомлений
Нажмите кнопку "Выполнить", чтобы создать проект и запустить приложение. Выберите некоторые критически важные параметры новостей, чтобы подписаться, а затем нажмите кнопку "Подписаться ". Должно появиться диалоговое окно, показывающее, что уведомления были подписаны.
При выборе подписки приложение преобразует выбранные категории в теги и запрашивает новую регистрацию устройства для выбранных тегов из центра уведомлений.
Введите сообщение, которое будет отправлено в качестве критических новостей, а затем нажмите кнопку "Отправить уведомление ". Кроме того, запустите консольное приложение .NET для создания уведомлений.
Каждое устройство, подписанное на критические новости, получает уведомления о критических новостях, которые вы только что отправили.
Дальнейшие действия
В этом руководстве вы отправили широковещательные уведомления определенным устройствам iOS, зарегистрированным для категорий. Чтобы узнать, как отправлять локализованные уведомления, перейдите к следующему руководству: