Поддержка интерактивных нотификаций iOS 8 в приложении

    Одним из нововведений iOS 8 являются интерактивные нотификации. Таким нотификациям можно назначить до четырех действий, каждое из которых будет представлено отдельной кнопкой внизу баннера с текстом нотификации. Таким образом, у пользователя появляются дополнительные возможности отреагировать на сообщения без активации (обычно) приложения. Рассмотрим, как добавить поддержку подобного функционала.

    Определение действий


    Во-первых, необходимо определить действия, которые можно выполнять над нотификацией. Делается это с помощью экземпляров класса UIMutableUserNotificationAction:

    UIMutableUserNotificationAction *action_like = [[UIMutableUserNotificationAction alloc] init];
    action_like.identifier = @"Like"; 
    action_like.title = NSLocalizedString(@"Like",nil); 
    action_like.activationMode = UIUserNotificationActivationModeBackground; 
    action_like.destructive = NO; 
    action_like.authenticationRequired = NO;
    

    Экземпляры данного класса содержат свойства:

    identifier — строка-идентификатор действия. Это свойство будет использоваться в дальнейшем, чтобы отличать действия друг от друга.
    title — заголовок, который будет показан на кнопке.
    activationMode — определяет, можно ли обрабатывать действие в бэкграунде или же приложение необходимо активировать.
    destructive — определяет, является ли действие деструктивным. Если да, кнопка такого действия будет выделена (обычно красным цветом).
    authenticationRequired — определяет, необходима ли аутентификация пользователя для выполнения действия.

    Пример определения деструктивного действия, для выполнения которого приложение будет активироваться:
    UIMutableUserNotificationAction *action_del = [[UIMutableUserNotificationAction alloc] init];
    action_del.identifier = @"Delete";
    action_del.title = NSLocalizedString(@"Delete",nil);
    action_del.activationMode = UIUserNotificationActivationModeForeground;
    action_del.destructive = YES;
    action_del.authenticationRequired = NO;
    

    Создание категории и регистрация параметров обработки нотификаций


    Во-вторых, мы должны создать категорию для наших нотификаций с помощью экземпляра класса UIMutableUserNotificationCategory :
    UIMutableUserNotificationCategory *category= [[UIMutableUserNotificationCategory alloc] init];
    category.identifier = @"my_category"; 
    [category setActions:@[action_like, action_del] forContext:UIUserNotificationActionContextDefault]; 
            
    NSSet *categories = [NSSet setWithObjects:category, nil];
    

    Идентификатор категории следует отправлять в качестве ключа category в pyaload'е push-нотификации или свойства category локальной нотификации.
    Аргумент forContext задает количество допустимых действий для нотификации.

    Регистрация:
    UIUserNotificationSettings *notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:categories];
            
    [[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
    


    Представление нотификации


    Отправив нотификацию следующего вида:
    {'aps': 
              {'alert': 'A sample of interactive notification text',
               'category': 'my_category',
               'some_id': 'my_id'
              }
    }
    

    (c учетом ограничений на размер payload'a категорию нотификации имеет смысл задавать не очень длинным идентификатором; но так как это учебный пример, то используется my_category), получим уведомления следующего вида.
    На lock- screen'е:
    image
    и после сдвига:
    image
    В области уведомлений:
    image
    И Notification center:
    image

    Обработка нажатия кнопок


    Для обработки нажатий на кнопки следует определить метод
    - application:handleActionWithIdentifier:forLocalNotification:completionHandler:
    

    для обработки локальных уведомлений.
    И
    - application:handleActionWithIdentifier:forRemoteNotification:completionHandler:
    

    для обработки push-уведомлений.
    Второй аргумент этих методов — это идентификатор действия, который мы ранее указывали как:
    action_del.identifier = @"Delete";
    

    Последний аргумент — это блок, который необходимо обязательно вызвать после обработки действия:
    - (void) application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void (^)())completionHandler {
        NSLog(@"NOTIFICATION IDENT: %@ USER INFO: %@", identifier, userInfo);
        
        completionHandler();
    }
    

    Обратите внимание, что нажатие на кнопку 'Like' не активирует приложение. В отличие от нажатия на 'Delete'.

    Заключение


    Таким образом, «легким движением руки» (с) можно добавить дополнительный функционал в приложение, увеличив его привлекательность для пользователя (во всяком случае, попытаться увеличить привлекательность).
    Метки:
    • +17
    • 9,3k
    • 9
    Поделиться публикацией
    Комментарии 9
    • +2
      А ввод текста без активации приложения, как сделано в Messages, можно сделать?
      Т.е. написать ответ прямо на экране блокировки.
      • 0
        Нет
        • 0
          Нет. Надо делать свой виджет для этого.
        • 0
          Полей всё больше, а длина payload всё ещё 256 байт?
          • 0
            2048
            • 0
              Насколько мне удалось нагуглить, только iOS8. От обратной совместимости придётся отказаться? Или 2k долетает и до iOS7?
              • 0
                Для iOS7 все те же 256 байт.
                • +2
                  Разумнее рассматривать их как 2 различных вида оповещений, а значит с отправкой токена для пуша отправлять и версию iOS юзера и хранить рядом. Ведь в интерактивном пуше вполне захочется написать другой текст, не как в обычном. В таком случае не возникнет проблемы обратной совместимости, если готовить пуши раздельно.
                  • +5
                    Могу подтвердить, что 2k payload поддерживается в iOS7. По крайней мере в sandbox environment такие уведомления приходят и обрабатываются устройством нормально. Более старые версии не проверял, но уверен, что изначально это ограничение только на стороне APNS-серверов Apple. Это также подтверждают и другие источники:

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