Регистрация, планируя и обрабатывая пользовательские уведомления

Нескольких задач, которые iOS или приложение OS X должны сделать для регистрации, планирует и обрабатывает и локальные и удаленные уведомления.

Регистрация для Типов Уведомления в iOS

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

В iOS используйте registerUserNotificationSettings: метод UIApplication зарегистрировать типы уведомления. Типы уведомления представляют элементы пользовательского интерфейса отображения приложения, когда это получает уведомление: применение идентификационных знаков значок приложения, играя звук, и выводя на экран предупреждение. Если Вы не регистрируете типов уведомления, система продвигает все удаленные уведомления Вашему приложению тихо, т.е. не выводя на экран пользовательского интерфейса. Перечисление 2-1 показывает, как приложение регистрирует типы уведомления.

Перечисление 2-1  , Регистрирующее типы уведомления

UIUserNotificationType types = UIUserNotificationTypeBadge |
             UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
 
UIUserNotificationSettings *mySettings =
            [UIUserNotificationSettings settingsForTypes:types categories:nil];
 
[[UIApplication sharedApplication] registerUserNotificationSettings:mySettings];

Заметьте использование categories параметр в Перечислении 2-1. Категория является группой действий, которые могут быть выведены на экран в сочетании с единственным уведомлением. Можно узнать больше о категориях в Использовании Действий Уведомления в iOS.

В первый раз Вы вызываете registerUserNotificationSettings: метод, iOS представляет диалоговое окно, просящее у пользователя разрешение представить типы уведомлений зарегистрированное приложение. После того, как пользователь отвечает, iOS асинхронно перезванивает к UIApplicationDelegate объект с application:didRegisterUserNotificationSettings: метод, передавая a UIUserNotificationType объект, указывающий типы уведомлений пользователь, позволяет.

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

В iOS 8 и позже, вызывая registerUserNotificationSettings: применяется к удаленным уведомлениям, а также локальным уведомлениям. Поскольку выполнение так указывает типы удаленных уведомлений отображения приложения, registerForRemoteNotificationTypes: осуждается в iOS 8. Можно узнать больше об удаленных уведомлениях в Регистрации для Удаленных Уведомлений.

Планирование локальных уведомлений

В iOS Вы создаете a UILocalNotification возразите и запланируйте его поставку с помощью scheduleLocalNotification: метод UIApplication. В OS X Вы создаете NSUserNotification объект (который включает время доставки), и NSUserNotificationCenter ответственно за поставку его соответственно. (Приложение OS X может также принять NSUserNotificationCenterDelegate протокол для настройки поведения значения по умолчанию NSUserNotificationCenter объект.)

Создание и планирование локальных уведомлений в iOS требуют, чтобы Вы выполнили следующие шаги:

  1. В iOS 8 и позже, зарегистрируйтесь для типов уведомления, как описано в Регистрации для Типов Уведомления в iOS. (В OS X и более ранних версиях iOS, Вы должны зарегистрироваться только для удаленных уведомлений.), Если Вы уже зарегистрировали типы уведомления, вызвать currentUserNotificationSettings для получения типов уведомлений, пользователь принимает из приложения.

  2. Выделите и инициализируйте a UILocalNotification объект.

  3. Установите дату и время, что операционная система должна поставить уведомление. Это fireDate свойство.

    Если Вы устанавливаете timeZone свойство к NSTimeZone объект для текущей локали, система автоматически корректирует дату огня, когда перемещения устройства через (и сбрасывается для), различные часовые пояса. (Часовые пояса влияют на значения компонентов даты — т.е. день, месяц, час, год и минута — который система вычисляет для данного календаря и значения даты.)

    Можно также запланировать уведомление для поставки на повторяющейся основе (ежедневно, еженедельно, ежемесячно, и т.д.).

  4. Как соответствующие, сконфигурируйте предупреждение, значок значка или звук так, чтобы уведомление могло быть поставлено пользователям согласно их предпочтениям. (Для приобретения знаний о том, когда различные типы уведомления будут надлежащими см. Уведомления.)

    • Предупреждение имеет свойство для сообщения ( alertBody свойство) и для заголовка кнопки действий или ползунка (alertAction). Укажите строки, локализующиеся для текущего языкового предпочтения пользователя. Если Ваши уведомления могут быть выведены на экран на Часах Apple, присвоить значение alertTitle свойство.

    • Для отображения числа в значке на значке приложения используйте applicationIconBadgeNumber свойство.

    • Для игры звука присвойте звук soundName свойство. Можно присвоить имя файла нелокализованного пользовательского звука в основном пакете приложения, или можно присвоиться UILocalNotificationDefaultSoundName получить системный звук по умолчанию. Звук должен всегда сопровождать дисплей предупредительного сообщения или применение идентификационных знаков значка; звук не должен играться в отсутствие других типов уведомления.

  5. Дополнительно, можно присоединить пользовательские данные к уведомлению через userInfo свойство. Например, уведомление, которое это отправляется, когда запись CloudKit изменения включает идентификатор записи, так, чтобы обработчик мог получить запись и обновить ее.

  6. Дополнительно, в iOS 8 и позже, Ваше локальное уведомление может представить пользовательские действия, которые Ваше приложение может выполнить в ответ на взаимодействие с пользователем, как описано в Использовании Действий Уведомления в iOS.

  7. Запланируйте локальное уведомление для поставки.

    Вы планируете локальное уведомление путем вызова scheduleLocalNotification:. Приложение использует дату огня, указанную в UILocalNotification возразите в настоящий момент поставки. Также можно сразу представить уведомление путем вызова presentLocalNotificationNow: метод.

Метод в Перечислении 2-2 создает и планирует уведомление, чтобы сообщить, что пользователь гипотетического приложения списка ожидающих выполнения задач о нависшей дате оплаты к - делает элемент. Существует пара вещей отметить об этом. Для alertBody, alertAction, и alertTitle свойства, это выбирает от основного пакета (через NSLocalizedString макрос) строки, локализованные на предпочтительный язык пользователя. Это также добавляет, что имя соответствующего для - делает элемент к словарю, присвоенному userInfo свойство.

  Создание перечисления 2-2, конфигурирование и планирование локального уведомления

- (void)scheduleNotificationWithItem:(ToDoItem *)item interval:(int)minutesBefore {
    NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];
    NSDateComponents *dateComps = [[NSDateComponents alloc] init];
    [dateComps setDay:item.day];
    [dateComps setMonth:item.month];
    [dateComps setYear:item.year];
    [dateComps setHour:item.hour];
    [dateComps setMinute:item.minute];
    NSDate *itemDate = [calendar dateFromComponents:dateComps];
 
    UILocalNotification *localNotif = [[UILocalNotification alloc] init];
    if (localNotif == nil)
        return;
    localNotif.fireDate = [itemDate dateByAddingTimeIntervalInterval:-(minutesBefore*60)];
    localNotif.timeZone = [NSTimeZone defaultTimeZone];
 
    localNotif.alertBody = [NSString stringWithFormat:NSLocalizedString(@"%@ in %i minutes.", nil),
         item.eventName, minutesBefore];
    localNotif.alertAction = NSLocalizedString(@"View Details", nil);
    localNotif.alerttitle = NSLocalizedString(@"Item Due", nil);
 
    localNotif.soundName = UILocalNotificationDefaultSoundName;
    localNotif.applicationIconBadgeNumber = 1;
 
    NSDictionary *infoDict = [NSDictionary dictionaryWithObject:item.eventName forKey:ToDoItemKey];
    localNotif.userInfo = infoDict;
 
    [[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
}

Можно отменить определенное запланированное уведомление путем вызова cancelLocalNotification: на объекте приложения, и можно отменить все запланированные уведомления путем вызова cancelAllLocalNotifications. Оба из этих методов также программно отклоняют в настоящее время выводимое на экран предупреждение уведомления. Например, Вы могли бы хотеть отменить уведомление, это связано с напоминанием, которое больше не хочет пользователь.

Приложения могли бы также счесть локальные уведомления полезными, когда они работают в фоновом режиме и некоторое сообщение, данные, или другой элемент поступает, который мог бы представлять интерес для пользователя. В этом случае приложение может сразу представить уведомление с помощью UIApplication метод presentLocalNotificationNow: (iOS дает приложению ограниченное время для выполнения в фоновом режиме).

В OS X Вы могли бы записать код как, который, как показывают в Перечислении 2-3, создал локальное уведомление и запланировать его для поставки. Если Ваше приложение в настоящее время frontmost, Обратите внимание на то, что OS X не поставляет локальное уведомление. Кроме того, пользователи OS X могут изменить свои предпочтения получения уведомлений в Установках системы.

  Создание перечисления 2-3 и планирование локального уведомления в OS X

//Create a new local notification
NSUserNotification *notification = [[NSUserNotification alloc] init];
//Set the title of the notification
notification.title = @"My Title";
//Set the text of the notification
notification.informativeText = @"My Text";
//Schedule the notification to be delivered 20 seconds after execution
notification.deliveryDate = [NSDate dateWithTimeIntervalSinceNow:20];
 
//Get the default notification center and schedule delivery
[[NSUserNotificationCenter defaultUserNotificationCenter] scheduleNotification:notification];

Регистрация для удаленных уведомлений

Приложение должно зарегистрироваться в Apple Push Notification service (APNs) для получения удаленных уведомлений, отправленных провайдером нажатия приложения. В iOS 8 и позже, регистрация имеет четыре этапа:

  1. Зарегистрируйтесь уведомление вводит Ваше использование поддержек приложений registerUserNotificationSettings:.

  2. Регистр для получения уведомлений нажатия через APNs путем вызова приложения registerForRemoteNotifications метод.

  3. Сохраните маркер устройства, возвращенный делегату приложения сервером для успешной регистрации или регистрационному отказу дескриптора корректно.

  4. Передайте маркер устройства провайдеру нажатия приложения.

(В iOS 7, вместо первых двух шагов, Вы регистрируетесь путем вызова registerForRemoteNotificationTypes: метод UIApplication, и в OS X путем вызова registerForRemoteNotificationTypes: метод NSApplication.) Действия, имеющие место во время регистрационной последовательности, проиллюстрированы рисунком 3-3 в Маркерной Генерации и Рассредоточении.

Маркеры устройства могут измениться, таким образом, Ваше приложение должно повторно зарегистрироваться каждый раз, когда оно запускается.

Если регистрация успешна, APNs возвращает маркер устройства устройству, и iOS передает маркер делегату приложения в application:didRegisterForRemoteNotificationsWithDeviceToken: метод. Приложение передает этот маркер, закодированный в двоичном формате, к его провайдеру. Если существует проблема в получении маркера, операционная система сообщает делегату путем вызова application:didFailToRegisterForRemoteNotificationsWithError: метод (или application:didFailToRegisterForRemoteNotificationsWithError: метод в OS X). NSError объект передал в этот метод, ясно описывает причину ошибки. Ошибка могла бы быть, например, ошибочным aps-environment значение в профиле настройки. Необходимо просмотреть ошибку как переходное состояние и не попытаться проанализировать ее.

Путем запроса маркера устройства и передачи его провайдеру каждый раз запуски приложения, Вы гарантируете, что провайдер имеет текущий маркер для устройства. Иначе, нажатия могут не пробиться к устройству пользователя. Если пользователь восстанавливает резервное копирование к устройству или компьютеру кроме того, для которого создавалось резервное копирование (например, пользователь перемещает данные на новое устройство или компьютер), пользователь должен запустить приложение, по крайней мере, один раз для него для получения уведомлений снова. Если пользователь восстанавливает данные резервного копирования к новому устройству или компьютеру, или переустанавливает операционную систему, маркерные изменения устройства. Кроме того, никогда не кэшируйте маркер устройства и дайте это своему провайдеру; всегда получайте маркер от системы каждый раз, когда Вам нужен он. Если Ваше приложение ранее зарегистрировалось, вызвав registerForRemoteNotifications результаты в операционной системе, передающей маркер устройства делегату сразу, не подвергаясь дополнительным издержкам. Также обратите внимание на то, что метод делегата может позвониться в любое время маркерные изменения устройства, не только в ответ на Вашу регистрацию приложения или перерегистрацию.

Перечисление 2-4 дает простой пример того, как Вы могли бы зарегистрироваться для удаленных уведомлений в приложении для iOS. Код был бы подобен для приложения Mac.

Перечисление 2-4  , Регистрирующееся для удаленных уведомлений

- (void)applicationDidFinishLaunching:(UIApplication *)app {
   // other setup tasks here....
    UIUserNotificationType types = UIUserNotificationTypeBadge |
                 UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
 
    UIUserNotificationSettings *mySettings =
                [UIUserNotificationSettings settingsForTypes:types categories:nil];
 
    [[UIApplication sharedApplication] registerUserNotificationSettings:mySettings];
    [app.registerForRemoteNotifications];
}
 
// Delegation methods
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken {
    const void *devTokenBytes = [devToken bytes];
    self.registered = YES;
    [self sendProviderDeviceToken:devTokenBytes]; // custom method
}
 
- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err {
    NSLog(@"Error in registration. Error: %@", err);
}

В Вашем application:didFailToRegisterForRemoteNotificationsWithError: реализация, необходимо обработать тот ошибочный объект соответственно и удостовериться, что Вы отключаете любую логику в своем приложении, зависящем от получения удаленных уведомлений. Вы не хотите, делают любую ненужную обработку в Вашем приложении для уведомлений, не бывших входящими. Просто корректно ухудшитесь.

Обработка локальных и удаленных уведомлений

Давайте рассмотрим возможные сценарии, которые могут возникнуть, когда система поставляет локальное уведомление или удаленное уведомление для приложения.

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

Пользователь касается кнопки пользовательского действия в уведомлении iOS 8. В этом случае iOS вызывает также application:handleActionWithIdentifier:forRemoteNotification:completionHandler: или application:handleActionWithIdentifier:forLocalNotification:completionHandler:. В обоих методах Вы получаете идентификатор действия так, чтобы можно было определить, которые нажимают на кнопку, пользователь коснулся. Вы также получаете или удаленный или локальный объект уведомления, так, чтобы можно было получить любую информацию, необходимо обработать действие.

Пользователь касается кнопки по умолчанию на предупреждении или касаниях (или щелчки) значок приложения. Если кнопка действий по умолчанию касается (на устройстве рабочий iOS), система запускает приложение, и приложение вызывает своего делегата application:didFinishLaunchingWithOptions: метод, передающий в полезной нагрузке уведомления (для удаленных уведомлений) или объект локального уведомления (для локальных уведомлений). Несмотря на то, что application:didFinishLaunchingWithOptions: не лучшее место для обработки уведомления, получать полезную нагрузку в этой точке дает Вам возможность запустить процесс обновления, прежде чем вызовут Ваш метод обработчиков.

Если уведомление является удаленным, система также вызывает application:didReceiveRemoteNotification:fetchCompletionHandler:.

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

Когда приложение работает на переднем плане, уведомление поставлено. Приложение вызывает UIApplicationDelegate метод application:didReceiveLocalNotification: или application:didReceiveRemoteNotification:fetchCompletionHandler:. (Если application:didReceiveRemoteNotification:fetchCompletionHandler: не реализован, системные вызовы application:didReceiveRemoteNotification:.) В OS X, системных вызовах application:didReceiveRemoteNotification:.

Приложение может использовать переданный - в полезной нагрузке удаленного уведомления или, в iOS, UILocalNotification возразите, чтобы помочь установить контекст для обработки элемента, связанного с уведомлением. Идеально, делегат делает следование каждой платформы для обработки поставки удаленных и локальных уведомлений во всех ситуациях:

Делегат к приложению для iOS в Перечислении 2-5 реализует application:didFinishLaunchingWithOptions: метод для обработки локального уведомления. Это получает связанное UILocalNotification объект из словаря опций запуска с помощью UIApplicationLaunchOptionsLocalNotificationKey ключ. От UILocalNotification объект userInfo словарь, это получает доступ к - делают элемент, который является причиной уведомления и использует его для установки начального контекста приложения. Если нет никаких выдающихся элементов — как часть обработки уведомления, как показано в этом примере, Вы могли бы соответственно сбросить число значка на значке приложения — или удалить его.

Перечисление 2-5  , Обрабатывающее локальное уведомление, когда запускается приложение

- (BOOL)application:(UIApplication *)app didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    UILocalNotification *localNotif =
        [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
    if (localNotif) {
        NSString *itemName = [localNotif.userInfo objectForKey:ToDoItemKey];
        [viewController displayItem:itemName];  // custom method
        app.applicationIconBadgeNumber = localNotif.applicationIconBadgeNumber-1;
    }
    [window addSubview:viewController.view];
    [window makeKeyAndVisible];
    return YES;
}

Реализация для удаленного уведомления была бы подобна, за исключением того, что Вы будете использовать специально заявленную константу в каждой платформе как ключ для доступа к полезной нагрузке уведомления:

Сама полезная нагрузка NSDictionary объект, содержащий элементы уведомления — предупредительное сообщение, число значка, звук, и т.д. Это может также содержать пользовательские данные, которые приложение может использовать для обеспечения контекста при установке интерфейса исходного пользователя. Посмотрите Полезную нагрузку Уведомления для подробных данных о полезной нагрузке удаленного уведомления.

При обработке удаленных уведомлений в методах обработки уведомления делегат приложения мог бы выполнить главную дополнительную задачу. Сразу после запусков приложения делегат должен соединиться с его провайдером и выбрать данные ожидания.

Код в Перечислении 2-6 показывает реализацию application:didReceiveLocalNotification: метод, который вызывают, когда приложение работает на переднем плане. Здесь делегат приложения выполняет ту же работу, как она делает в Перечислении 2-5. Это может получить доступ UILocalNotification возразите непосредственно на сей раз, потому что этот объект является параметром метода.

Перечисление 2-6  , Обрабатывающее локальное уведомление, когда уже работает приложение

- (void)application:(UIApplication *)app didReceiveLocalNotification:(UILocalNotification *)notif {
    NSString *itemName = [notif.userInfo objectForKey:ToDoItemKey];
    [viewController displayItem:itemName];  // custom method
    app.applicationIconBadgeNumber = notification.applicationIconBadgeNumber - 1;
}

Если Вы хотите, чтобы Ваше приложение поймало удаленные уведомления, которые поставляет система, в то время как это работает на переднем плане, делегат приложения должен реализовать application:didReceiveRemoteNotification:fetchCompletionHandler: метод. Делегат должен начать процедуру для загрузки данных ожидания, сообщения или другого элемента и, после того, как это завершает, это должно удалить значок из значка приложения. Словарь, переданный во втором параметре этого метода, является полезной нагрузкой уведомления; Вы не должны использовать пользовательские свойства, которые это содержит для изменения текущего контекста приложения.

Используя Действия Уведомления в iOS

В OS X и версиях iOS до iOS 8, пользовательские уведомления могут иметь только одно действие по умолчанию. В iOS 8 и позже, пользовательские уведомления могут иметь дополнительные пользовательские действия. Два действия могут быть выведены на экран на экране блокировки в баннере, и в Центре Уведомления. Когда пользователь касается кнопки Options, на модальных предупреждениях уведомления могут вывести на экран до четырех действий. Для использования действий уведомления в приложении необходимо зарегистрировать действия, запланировать локальное уведомление или продвинуть удаленное уведомление и обработать действие, выбранное пользователем.

Регистрация действий уведомления

Для использования действий уведомления в приложении необходимо определить действия, сгруппировать их в категории, и затем зарегистрировать их в приложении, совместно использовал UIApplication экземпляр.

Для определения действия уведомления сначала необходимо создать и инициализировать экземпляр класса действия уведомления, обычно UIMutableUserNotificationAction. Тогда Вы определяете идентификатор, пасуемый назад к Вашему приложению, когда оно обрабатывает действие и локализованную строку, выведенную на экран пользователю на кнопке действий. Если действие должно прервать пользователя или фон если нет, Затем, Вы устанавливаете режим активации действия в передний план. Наконец, Вы объявляете, является ли действие разрушительным, означая его красные дисплеи кнопки, и требует ли выбор действия, чтобы пользователь ввел их код доступа. Перечисление 2-7 иллюстрирует эти шаги.

Перечисление 2-7  , Определяющее действие уведомления

UIMutableUserNotificationAction *acceptAction =
            [[UIMutableUserNotificationAction alloc] init];
 
// Define an ID string to be passed back to your app when you handle the action
acceptAction.identifier = @"ACCEPT_IDENTIFIER";
 
// Localized string displayed in the action button
acceptAction.title = @"Accept";
 
// If you need to show UI, choose foreground
acceptAction.activationMode = UIUserNotificationActivationModeBackground;
 
// Destructive actions display in red
acceptAction.destructive = NO;
 
// Set whether the action requires the user to authenticate
acceptAction.authenticationRequired = NO;

activationMode свойство определяет, запускает ли iOS Ваше приложение на переднем плане или фоне, когда пользователь реагирует на уведомление. Если Вы устанавливаете его в UIUserNotificationActivationModeBackground, Вашему приложению дают секунды для выполнения. Если destructive свойство NO, кнопка действия кажется синей; если это YES, кнопка является красной. Если Вы устанавливаете действие authenticationRequired свойство к YES и устройство заблокировано, когда пользователь реагирует на уведомление, пользователь должен ввести код доступа при выборе действия. Однако это не разблокировало устройство, поэтому если Ваше приложение должно получить доступ к файлам, удостоверьтесь, что файлы находятся в правильном классе защиты данных. Когда значение activationMode свойство UIUserNotificationActivationModeForeground, значение authenticationRequired свойство, как предполагается, YES независимо от его фактического значения.

Например, для конфигурирования действий для календарного приложения для Принять действия не нужно никакое дополнительное взаимодействие с пользователем после того, как пользователь коснется кнопки Accept, таким образом, activationMode может быть фон. Кроме того, Принять действие не является разрушительным, таким образом, это не появляется в красном на уведомлении и блокирует экран, и этому не нужна аутентификация, потому что принятие приглашения относительно безопасно. Как другой пример, для действия Мусора для удаления сообщения в Почтовом приложении также не нужно никакое дальнейшее взаимодействие с пользователем, таким образом, это может работать в фоновом режиме, но это является разрушительным, таким образом, destructive свойство должно быть установлено в YES, и это требует аутентификации, потому что Вы не хотите кого-то еще удаляющего Ваши сообщения. С другой стороны, действие Ответа требует взаимодействия с пользователем, таким образом, режим активации должен быть передним планом. Это не является разрушительным, но пользователь должен разблокировать устройство, потому что приоритетные действия всегда требуют аутентификации, независимо от значения в authenticationRequired свойство.

После определения действий необходимо сгруппировать каждого из них в категорию, связывающую тип уведомления с рядом связанных действий. Например, Пригласить категория могла иметь, Принимают, Возможно, и действия Снижения. Новая почтовая категория могла иметь Знак как Рида и Мусор, и Маркированная категория могла иметь Как, Комментарий и действия Нетега. При обработке локальных или удаленных уведомлений для устройства пользователя Вы указываете категорию, содержащую действия, которые Вы хотите вывести на экран с тем уведомлением. Когда уведомление выведено на экран, iOS использует информацию о категории для определения, какие кнопки вывести на экран на предупреждении уведомления и уведомить Вас, которого действия пользователь выбрал.

К действиям группы в категорию создайте и инициализируйте экземпляр класса категории уведомления, обычно UIMutableUserNotificationCategory. Тогда определите идентификатор для категории, которую Вы включаете в локальные уведомления и полезную нагрузку нажатия удаленных уведомлений.

Затем Вы добавляете действия к категории и устанавливаете их контекст действия. Существует два пользовательских контекста действия уведомления: контекст по умолчанию, поддерживающий четыре действия и минимальный контекст, выводящий на экран два. Контекст касается части пользовательского интерфейса, в котором уведомление представлено — экран блокировки только имеет пространство для отображения двух действий, таким образом, минимальный контекст применяется, тогда как модальное предупреждение имеет пространство для полного набора действий, и контекст по умолчанию применяется. Перечисление 2-8 показывает, как могут быть кодированы эти шаги.

Перечисление 2-8  , Группирующее действия в категории

// First create the category
UIMutableUserNotificationCategory *inviteCategory =
        [[UIMutableUserNotificationCategory alloc] init];
 
// Identifier to include in your push payload and local notification
inviteCategory.identifier = @"INVITE_CATEGORY";
 
// Add the actions to the category and set the action context
[inviteCategory setActions:@[acceptAction, maybeAction, declineAction]
    forContext:UIUserNotificationActionContextDefault];
 
// Set the actions to present in a minimal context
[inviteCategory setActions:@[acceptAction, declineAction]
    forContext:UIUserNotificationActionContextMinimal];

Два setActions:forContext: сообщения в Перечислении 2-8 гарантируют, что действия представлены в правильном порядке в контексте по умолчанию, и что самые важные действия представлены в минимальном контексте. Т.е. на модальном предупреждении выведенные на экран действия, Принимают, Возможно, и Снижение (в том порядке), но на блокировке экранируют эти два выведенные на экран действия, Принимают и Снижение. Если второе setActions:forContext: не были указаны, только первые два действия контекста по умолчанию будут выведены на экран на экране блокировки: Примите и Возможно.

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

Перечисление 2-9  , Регистрирующее категории уведомления

NSSet *categories = [NSSet setWithObjects:inviteCategory, alarmCategory, ...
 
UIUserNotificationSettings *settings =
       [UIUserNotificationSettings settingsForTypes:types categories:categories];
 
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];

UIUserNotificationSettings метод класса settingsForTypes:categories: метод - тот же самый показанный в передавшем Перечислении 2-1 nil для categories параметр и настройки уведомлений регистрируются таким же образом с экземпляром приложения. В этом случае категории уведомления, а также типы уведомления, включены в настройки уведомлений приложения.

Продвижение удаленного уведомления или планирование локального уведомления с пользовательскими действиями

Чтобы показать действия уведомления, что Вы определили, категоризированный, и зарегистрировались, необходимо продвинуть удаленное уведомление или запланировать локальное уведомление. В удаленном случае уведомления необходимо включать идентификатор категории в полезную нагрузку нажатия, как показано в Перечисление 2-10. Поддержка категорий является сотрудничеством между Вашим приложением для iOS и Вашим сервером уведомления нажатия. Когда Ваш сервер нажатия хочет отправить уведомление пользователю, он может добавить ключ категории с надлежащим значением к полезной нагрузке уведомления. Когда iOS видит уведомление нажатия с ключом категории, это ищет категории, зарегистрированные приложением. Если iOS находит соответствие, оно выводит на экран соответствующие действия с уведомлением.

В iOS 8 предыдущий предел размера 256 байтов для полезной нагрузки нажатия был увеличен до 2 килобайтов. Посмотрите Полезную нагрузку Уведомления для подробных данных о полезной нагрузке удаленного уведомления.

  Полезная нагрузка Нажатия перечисления 2-10 включая идентификатор категории

{
    "aps" :  {
        "alert" : "You’re invited!",
        "category" : "INVITE_CATEGORY",
    }
}

В случае локального уведомления Вы создаете уведомление, как обычно, затем устанавливаете категорию действий, которые будут представлены, и наконец, планируете уведомление, как обычно, как показано в Перечислении 2-11.

Перечисление 2-11  , Определяющее категорию действий для локального уведомления

UILocalNotification *notification = [[UILocalNotification alloc] init];
. . .
notification.category = @"INVITE_CATEGORY";
[[UIApplication sharedApplication] scheduleLocalNotification:notification];

Обработка действий уведомления

Если Ваше приложение не работает на переднем плане, для обработки действия по умолчанию, когда пользователь просто сильно ударяет или касается на уведомлении, iOS запускает приложение на переднем плане и вызывает UIApplicationDelegate метод application:didFinishLaunchingWithOptions: передача в локальном уведомлении или удаленном уведомлении в options словарь. В удаленном случае уведомления система также вызывает application:didReceiveRemoteNotification:fetchCompletionHandler:.

Если Ваше приложение уже находится на переднем плане, iOS не показывает уведомление. Вместо этого для обработки действия по умолчанию это вызывает один из UIApplicationDelegate методы application:didReceiveLocalNotification: или application:didReceiveRemoteNotification:fetchCompletionHandler:. (Если Вы не реализуете application:didReceiveRemoteNotification:fetchCompletionHandler:, вызовы iOS application:didReceiveRemoteNotification:.)

Наконец, для обработки пользовательских действий, доступных в iOS 8, необходимо реализовать по крайней мере один из двух новых методов на делегате приложения, application:handleActionWithIdentifier:forRemoteNotification:completionHandler: или application:handleActionWithIdentifier:forLocalNotification:completionHandler:. В любом случае Вы получаете идентификатор действия, который можно использовать для определения, какое действие коснулось. Вы также получаете уведомление, удаленное или локальное, который можно использовать для получения любой информации, необходимо обработать то действие. Наконец, система передает Вас обработчик завершения, который необходимо вызвать, когда Вы заканчиваете обрабатывать действие. Перечисление 2-12 показывает реализацию в качестве примера, вызывающую самоопределенный метод обработчиков действия.

Перечисление 2-12  , Обрабатывающее пользовательское действие уведомления

- (void)application:(UIApplication *) application
              handleActionWithIdentifier: (NSString *) identifier
          // either forLocalNotification: (NSDictionary *) notification or
                   forRemoteNotification: (NSDictionary *) notification
                       completionHandler: (void (^)()) completionHandler {
 
    if ([identifier isEqualToString: @"ACCEPT_IDENTIFIER"]) {
        [self handleAcceptActionWithNotification:notification];
    }
 
    // Must be called when finished
    completionHandler();
}

Используя основанные на местоположении уведомления

В iOS 8 и позже, можно отправить пользователю уведомление каждый раз, когда они достигают определенного географического местоположения. Эта опция использует Базовое Расположение и реализована посредством простых дополнений API к UILocalNotification класс. Вы определяете Базовые объекты области Расположения и присоединяете их к уведомлению так, чтобы уведомление стреляло, когда пользователь подходит, вводит или выходит из области. Можно сделать его так, чтобы уведомление было представлено только в первый раз, когда пользователь вводит эту область, или у Вас мог быть огонь уведомлений постоянно, если это целесообразно для Вашего приложения.

Регистрация для основанных на местоположении уведомлений

Прежде чем можно будет запланировать основанное на местоположении уведомление, необходимо зарегистрироваться в Базовом Расположении. Для регистрации создайте a CLLocationManager экземпляр и набор Ваше приложение как делегат на этом менеджере. Делегат получает обратные вызовы, говорящие Ваше приложение, позволяется ли отследить расположение пользователя. Наконец, необходимо отправить менеджеру расположения экземпляр a requestWhenInUseAuthorization сообщение, как показано в Перечислении 2-13. В первый раз, когда Ваше приложение вызывает этот метод, оно выводит на экран предупреждение, просящее, чтобы пользователь позволил или запретил отслеживание Вашего приложения местонахождения пользователя. В дополнение к тому, чтобы просить, чтобы пользователь для разрешения для Вашего приложения получил доступ к их расположению, предупреждение также выводит на экран некоторый объяснительный текст, который Вы обеспечиваете, такие как “Включение отслеживания расположения позволяет друзьям видеть, где Вы”. Эта объяснительная строка требуется, чтобы использовать службы определения местоположения. Ваше приложение определяет строку в Info.plist файл под NSLocationWhenInUseUsageDescription ключ. Если Ваше выполнение приложения в локалях с различными языками, удостоверьтесь, что Вы локализуете строку соответственно в Вашем Info.plist строковый файл. Если пользователь соглашается предоставить доступ, Ваше приложение может отследить расположение пользователя, когда Ваше приложение работает на переднем плане.

Перечисление 2-13  , Получающее авторизацию для отслеживания расположения пользователя

CLLocationManager *locMan = [[CLLocationManager alloc] init];
// Set a delegate that receives callbacks that specify if your app is allowed to track the user's location
locMan.delegate = self;
 
// Request authorization to track the user’s location and enable location-based notifications
[locMan requestWhenInUseAuthorization];

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

Обработка базовых обратных вызовов расположения

При запуске необходимо проверить состояние авторизации и хранить информацию состояния, которую необходимо позволить или запретить основанные на местоположении уведомления. Первый обратный вызов делегата от Базового менеджера Расположения, которого необходимо обработать, locationManager:didChangeAuthorizationStatus:, который сообщает об изменениях в состоянии авторизации. Во-первых, проверьте, что состояние, переданное с обратным вызовом, kCLAuthorizationStatusAuthorizedWhenInUse, как показано в Перечислении 2-14, означая, что Ваше приложение разрешено отследить расположение пользователя. Тогда можно начать планировать основанные на местоположении уведомления.

Перечисление 2-14  , Обрабатывающее Базовый обратный вызов авторизации Расположения

- (void)locationManager:(CLLocationManager *)manager
               didChangeAuthorizationStatus:(CLAuthorizationStatus)status {
 
    // Check status to see if the app is authorized
    BOOL canUseLocationNotifications = (status == kCLAuthorizationStatusAuthorizedWhenInUse);
 
    if (canUseLocationNotifications) {
        [self startShowingLocationNotifications]; // Custom method defined below
    }
}

Перечисление 2-15 показывает, как запланировать уведомление, инициировавшее, когда пользователь вводит область. Первая вещь, которую необходимо сделать, как с локальным уведомлением, инициированным датой или время, состоит в том, чтобы создать экземпляр UILocalNotification и определите его тип, в этом случае предупреждение.

Перечисление 2-15  Планируя основанное на местоположении уведомление

- (void)startShowingNotifications {
 
    UILocalNotification *locNotification = [[UILocalNotification alloc] init];
    locNotification.alertBody = @“You have arrived!”;
    locNotification.regionTriggersOnce = YES;
 
    locNotification.region = [[CLCircularRegion alloc]
                        initWithCenter:LOC_COORDINATE
                                radius:LOC_RADIUS
                            identifier:LOC_IDENTIFIER];
 
    [[UIApplication sharedApplication] scheduleLocalNotification:locNotification];
}

Когда пользователь вводит область, определенную в Перечисление 2-15, предполагая, что приложение не работает на переднем плане, отображения приложения предупредительное высказывание: “Вы поступили!» Следующая строка указывает, что это уведомление инициировало только один раз, в первый раз, когда пользователь вводит или выходит из этой области. Это - фактически поведение по умолчанию, таким образом, это является лишним для указания YES, но Вы могли установить это свойство в NO если это целесообразно для Ваших пользователей и для Вашего приложения.

Затем, Вы создаете a CLCircularRegion экземпляр и набор это на свойстве области UILocalNotification экземпляр. В этом случае мы даем ему определенную с помощью приложения координату места с некоторым радиусом так, чтобы, когда пользователь вводит этот круг, было инициировано это уведомление. Этот пример использует a CLCircularRegion свойство, но Вы могли также использовать CLBeaconRegion или любой другой тип CLRegion подкласс.

Наконец, вызвать scheduleLocalNotification: на Вашем UIApplication совместно используемый экземпляр, передавая это уведомление точно так же, как Вы сделали бы для любого другого уведомления локального пользователя.

Обработка основанных на местоположении уведомлений

Предположение, что Ваше приложение приостановлено, когда пользователь вводит область, определенную в Перечисление 2-15, предупреждение, выведено на экран, который говорит: «Вы поступили». Ваше приложение может обработать то локальное уведомление в application:didFinishLaunchingWithOptions: обратный вызов метода делегата приложения. Также, если Ваше приложение выполняется на переднем плане, когда пользователь вводит ту область, Ваш делегат приложения призван обратно с application:didReceiveLocalNotification: сообщение.

Логика для обработки основанного на местоположении уведомления очень подобна для обоих application:didFinishLaunchingWithOptions: и application:didReceiveLocalNotification: методы. Оба метода обеспечивают уведомление, экземпляр UILocalNotification, который имеет a region свойство. Если то свойство не nil, тогда уведомление является основанным на местоположении уведомлением, и можно сделать то, что целесообразно для приложения. Пример кода в Перечислении 2-16 вызывает гипотетический метод названного делегата приложения tellFriendsUserArrivedAtRegion:.

Перечисление 2-16  , Обрабатывающее основанное на местоположении уведомление

- (void)application:(UIApplication *)application
                         didReceiveLocalNotification: (UILocalNotification *)notification {
 
    CLRegion *region = notification.region;
 
    if (region) {
           [self tellFriendsUserArrivedAtRegion:region];
    }
}

Наконец, помните что application:didReceiveLocalNotification: метод не вызывают, если пользователь отключает Базовое Расположение, которое они могут сделать в любое время в приложении Настроек под Конфиденциальностью> Службы определения местоположения.

Подготовка пользовательских предупредительных звуков

Для удаленных уведомлений в iOS можно указать пользовательский звук, который играет iOS, когда он представляет локальное или удаленное уведомление для приложения. Звуковые файлы должны быть в основном пакете клиентского приложения.

Пользовательские предупредительные звуки играются средством системного звука iOS, таким образом, они должны быть в одном из следующих форматов аудиоданных:

Можно упаковать аудиоданные в aiff, wav, или caf файл. Затем в XCode добавьте звуковой файл к своему проекту как нелокализованный ресурс комплекта приложений.

Можно использовать afconvert инструмент для преобразования звуков. Например, для преобразования 16-разрядного линейного системного звука PCM Submarine.aiff к аудио IMA4 в файле CAF используйте следующую команду в Терминальном приложении:

afconvert /System/Library/Sounds/Submarine.aiff ~/Desktop/sub.caf -d ima4 -f caff -v

Можно проверить звук для определения его формата данных путем открытия его в QuickTime Player и выбора Show Movie Inspector из меню Movie.

Пользовательские звуки должны быть младше 30 секунд, когда играется. Если пользовательский звук по тому пределу, системный звук по умолчанию играется вместо этого.

Передача провайдера текущее языковое предпочтение (удаленные уведомления)

Если приложение не использует loc-key и loc-args свойства aps словарь для выборки клиентской стороны локализованных предупредительных сообщений, провайдер должен локализовать текст предупредительных сообщений, это вставляет полезную нагрузку уведомления. Чтобы сделать это, однако, провайдер должно знать язык, который пользователь устройств выбрал как предпочтительный язык. (Пользователь устанавливает это предпочтение в представлении General> International> Language приложения Настроек.) Клиентское приложение должно отправить его провайдеру идентификатор предпочтительного языка; это могло быть каноническим идентификатором IETF BCP 47 языка, таким как «en» или «франк».

Перечисление 2-17 иллюстрирует метод для получения в настоящее время выбираемого языка и передачи его к провайдеру. В iOS, массив, возвращенный preferredLanguages свойство NSLocale содержит один объект: NSString объект, инкапсулирующий код языка, идентифицирующий предпочтительный язык. UTF8String убежища строка возражают против струны до, закодированной как UTF8.

Перечисление 2-17  , Получающее текущий поддерживаемый язык и отправляющее его в провайдера

NSString *preferredLang = [[NSLocale preferredLanguages] objectAtIndex:0];
const char *langStr = [preferredLang UTF8String];
[self sendProviderCurrentLanguage:langStr]; // custom method
}

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

Если предпочтительный язык не один поддержки приложений, провайдер должен локализовать текст сообщения на языке нейтрализации, на котором широко говорят, таком как английский или испанский язык.