Как обрабатываются push-уведомления в iOS, когда приложение открыто и когда закрыто?

«Как обрабатываются push-уведомления в iOS, когда приложение открыто и когда закрыто?» — вопрос из категории Сети, который задают на 10% собеседований IOS Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Механизм обработки зависит от состояния приложения (foreground/background или terminated).

Когда приложение открыто (foreground):

  • Уведомление доставляется напрямую в код приложения.
  • Для UserNotifications framework (iOS 10+) вызывается метод делегата UNUserNotificationCenterDelegate:
    func userNotificationCenter(_ center: UNUserNotificationCenter,
                                willPresent notification: UNNotification,
                                withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
        // Решение: показать уведомление в интерфейсе или обработать тихо
        completionHandler([.banner, .sound, .badge])
    }
  • Для устаревшего подхода может вызываться application(_:didReceiveRemoteNotification:fetchCompletionHandler:) в AppDelegate.

Когда приложение закрыто (terminated) или в фоне (background):

  1. Система отображает баннер, звук и значок (badge).
  2. При тапе пользователя на уведомление:
    • Если приложение было закрыто, оно запускается, и в application(_:didFinishLaunchingWithOptions:) доступны данные уведомления в launchOptions[.remoteNotification].
    • Если приложение было в фоне, оно переходит в foreground, и вызывается application(_:didReceiveRemoteNotification:fetchCompletionHandler:) или userNotificationCenter(_:didReceive:withCompletionHandler:).

Практическое отличие: В foreground вы должны явно решить, как отобразить уведомление (например, через completionHandler). В background/terminated системный баннер показывается автоматически, а ваше приложение получает данные для обработки после взаимодействия пользователя.