Кастомизация push-уведомлений в iOS
Когда iOS-устройство получает уведомление с оповещением, система отображает его содержимое в два этапа. Сначала она показывает сокращенный баннер с заголовком, подзаголовком и двумя-четырьмя строками основного текста уведомления. Если пользователь нажимает на сокращенный баннер, iOS отображает полный интерфейс уведомления, включая любые связанные с ним действия. Система предоставляет интерфейс для сокращенного баннера, но вы можете кастомизировать полный интерфейс с помощью расширения приложения для контента уведомлений (notification content app extension).

Расширение для контента уведомлений управляет view-контроллером, который отображает ваш кастомный интерфейс уведомления. Этот view-контроллер может дополнять или заменять стандартный системный интерфейс для ваших уведомлений. Вы можете использовать свой view-контроллер, чтобы:
- Настроить расположение элементов, включая заголовок, подзаголовок и основной текст оповещения.
- Использовать другие шрифты или стили для элементов интерфейса.
- Отображать специфичные для приложения данные, например, данные, хранящиеся в специальных ключах полезной нагрузки (payload) уведомления.
- Включать кастомные изображения или брендинг.
Ваше расширение приложения должно настраивать свой view-контроллер, используя немедленно доступные данные, такие как содержимое уведомления и файлы, находящиеся в пакете (bundle) вашего расширения. Если вы используете группу приложений (app group) для обмена данными между вашим приложением и расширением, вы также можете использовать любые файлы, найденные в этой группе. Чтобы обеспечить своевременную доставку уведомлений, настраивайте представления (views) как можно быстрее. Не выполняйте длительных задач, таких как попытка получения данных по сети.
Добавление расширения для контента уведомлений в ваш проект
Anchor link toЧтобы добавить расширение для контента уведомлений в ваше iOS-приложение:
- В Xcode выберите File > New > Target.
- В разделе iOS Application Extension выберите Notification Content Extension.
- Нажмите Next.
- Укажите имя для вашего расширения.
- Нажмите Finish.
Добавление представлений (views) в ваш view-контроллер
Anchor link toШаблон, предоставляемый Xcode, включает storyboard и view-контроллер для настройки. Создайте свой кастомный интерфейс уведомления, добавляя представления (views) в ваш view-контроллер. Например, используйте лейблы (labels) для отображения заголовка, подзаголовка и основного текста уведомления. Вы также можете добавлять представления изображений (image views) и представления, которые отображают неинтерактивный контент. Вам не нужно предоставлять какой-либо начальный контент для ваших представлений.
В iOS 12 и более поздних версиях вы можете добавлять интерактивные элементы управления (например, кнопки или переключатели). Для получения дополнительной информации см. раздел «Поддержка интерактивных элементов управления».
Настройка вашего view-контроллера
Anchor link toИспользуйте метод didReceive(_:)
вашего view-контроллера для обновления его лейблов и других представлений. Полезная нагрузка (payload) уведомления содержит данные, которые следует использовать при настройке view-контроллера. Вы также можете использовать данные из других файлов вашего расширения. В Листинге 1 показана версия этого метода, которая извлекает заголовок и основной текст из полезной нагрузки уведомления и присваивает эти строки двум элементам управления UILabel
, которые хранятся как аутлеты (outlets) в view-контроллере.
// Настройка интерфейса уведомления во время выполнения
func didReceive(_ notification: UNNotification) { self.bodyText?.text = notification.request.content.body self.headlineText?.text = notification.request.content.title}
Если второе уведомление приходит, когда ваш view-контроллер уже виден, система снова вызывает метод didReceive(_:)
с новой полезной нагрузкой уведомления.
Поддержка интерактивных элементов управления
Anchor link toВ iOS 12 и более поздних версиях вы можете включить взаимодействие с пользователем в ваших кастомных уведомлениях. Это позволяет добавлять интерактивные элементы управления, такие как кнопки и переключатели, в ваш кастомный интерфейс.
Чтобы включить взаимодействие с пользователем:
- Откройте файл
info.plist
вашего Notification Content Extension. - Добавьте ключ
UNNotificationExtensionUserInteractionEnabled
в атрибуты вашего расширения. Присвойте ему булево значениеYES
.

Добавление Apple Pay в расширение push-уведомлений (пример представления)
Anchor link toПример блока кода с кнопкой Apple Pay в расширении Push-уведомлений
Anchor link toimport UIKitimport Foundationimport UserNotificationsimport UserNotificationsUIimport PassKit
class NotificationViewController: UIViewController, UNNotificationContentExtension, PKPaymentAuthorizationViewControllerDelegate {
func paymentAuthorizationViewControllerDidFinish(_ controller: PKPaymentAuthorizationViewController) { controller.dismiss(animated: true, completion: nil) }
@IBOutlet weak var buyWithApplePayButton: UIButton! @IBOutlet weak var containerView: UIView! @IBOutlet weak var payInAppButton: UIButton! @IBOutlet weak var segmentCustom: UISegmentedControl!
private var amount: NSDecimalNumber = 0;
override func viewDidLoad() { super.viewDidLoad()
buttonCustomisation()
amount = NSDecimalNumber.init(value: 5) }
func buttonCustomisation () { self.buyWithApplePayButton.layer.masksToBounds = true self.buyWithApplePayButton.layer.cornerRadius = 10 self.payInAppButton.layer.masksToBounds = true self.payInAppButton.layer.cornerRadius = 10 self.containerView.layer.borderColor = UIColor.gray.cgColor self.containerView.layer.borderWidth = 0.7 self.containerView.layer.masksToBounds = true self.containerView.layer.cornerRadius = 20 }
func didReceive(_ notification: UNNotification) { // Configuring the notification interface at runtime }
@IBAction func buyWithApplePayAction(_ sender: Any) { let request = PKPaymentRequest() request.merchantIdentifier = "merchant.com.sample.ApplePayAction" request.supportedNetworks = [PKPaymentNetwork.visa, PKPaymentNetwork.masterCard, PKPaymentNetwork.amex] request.merchantCapabilities = PKMerchantCapability.capability3DS request.countryCode = "US" request.currencyCode = "USD"
request.paymentSummaryItems = [ PKPaymentSummaryItem(label: "Some Product", amount: amount) ]
let applePayController = PKPaymentAuthorizationViewController(paymentRequest: request) applePayController?.delegate = self self.present(applePayController!, animated: true, completion: nil) }
@IBAction func payInAppButtonAction(_ sender: Any) { print("pay in app button tapped") }
@IBAction func segmentAction(_ sender: Any) { switch segmentCustom.selectedSegmentIndex { case 0: amount = NSDecimalNumber.init(value: 5) break case 1: amount = NSDecimalNumber.init(value: 10) break case 2: amount = NSDecimalNumber.init(value: 20) break default: amount = NSDecimalNumber.init(value: 5) break } }}