← Назад к вопросам
Что нужно реализовать в коде, чтобы приложение могло обрабатывать push-уведомления?
2.2 Middle🔥 121 комментариев
#Архитектура и паттерны#Работа с сетью
Комментарии (1)
🐱
deepseek-v3.2PrepBro AI5 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Полная реализация обработки Push-уведомлений в iOS
Чтобы приложение могло обрабатывать push-уведомления, необходимо реализовать многоуровневую настройку, включающую регистрацию устройства, конфигурацию проекта, обработку токенов и логику для различных состояний приложения. Вот пошаговая реализация:
1. Настройка Capabilities и сертификатов
Capabilities в Xcode:
// В Xcode:
// 1. Targets → Signing & Capabilities
// 2. Добавить capability "Push Notifications"
// 3. Добавить capability "Background Modes"
// 4. В Background Modes включить "Remote notifications"
Конфигурация сервера APNs:
- Создать сертификат/ключ в Apple Developer Portal
- Для разработки: Apple Push Notification service SSL (Sandbox)
- Для продакшена: Apple Push Notification service SSL (Production)
2. Регистрация устройства для получения токена
Базовая регистрация в AppDelegate:
import UIKit
import UserNotifications
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Запрос разрешения на уведомления
let center = UNUserNotificationCenter.current()
center.delegate = self
let options: UNAuthorizationOptions = [.alert, .sound, .badge]
center.requestAuthorization(options: options) { granted, error in
if let error = error {
print("Ошибка запроса разрешения: \(error.localizedDescription)")
}
if granted {
print("Разрешение получено")
DispatchQueue.main.async {
// Регистрация для удаленных уведомлений
application.registerForRemoteNotifications()
}
} else {
print("Разрешение отклонено пользователем")
}
}
return true
}
}
3. Обработка токена устройства
Получение и отправка токена на сервер:
extension AppDelegate {
// Успешная регистрация - получение device token
func application(_ application: UIApplication,
didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
// Преобразование Data в строку
let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) }
let token = tokenParts.joined()
print("Device Token: \(token)")
// Отправка токена на ваш сервер
sendTokenToServer(token)
}
// Ошибка регистрации
func application(_ application: UIApplication,
didFailToRegisterForRemoteNotificationsWithError error: Error) {
print("Не удалось зарегистрироваться: \(error.localizedDescription)")
}
private func sendTokenToServer(_ token: String) {
guard let url = URL(string: "https://ваш-сервер.com/register-device") else { return }
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let body: [String: Any] = [
"deviceToken": token,
"platform": "ios",
"appVersion": Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? ""
]
request.httpBody = try? JSONSerialization.data(withJSONObject: body)
URLSession.shared.dataTask(with: request) { data, response, error in
// Обработка ответа сервера
}.resume()
}
}
4. Обработка входящих уведомлений
Обработка в UNUserNotificationCenterDelegate:
extension AppDelegate: UNUserNotificationCenterDelegate {
// Уведомление получено, когда приложение активно
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) {
let userInfo = notification.request.content.userInfo
// Извлечение данных из уведомления
if let aps = userInfo["aps"] as? [String: Any],
let alert = aps["alert"] as? [String: String] {
print("Заголовок: \(alert["title"] ?? "")")
print("Текст: \(alert["body"] ?? "")")
}
// Отображение уведомления даже когда приложение активно
completionHandler([.banner, .sound, .badge])
}
// Пользователь тапнул по уведомлению
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
let userInfo = response.notification.request.content.userInfo
// Глубокая навигация
handleNotificationNavigation(with: userInfo)
// Очистка бейджа
UIApplication.shared.applicationIconBadgeNumber = 0
completionHandler()
}
private func handleNotificationNavigation(with userInfo: [AnyHashable: Any]) {
// Пример обработки deep link
if let screenType = userInfo["screenType"] as? String {
NotificationCenter.default.post(name: NSNotification.Name("NavigateToScreen"),
object: nil,
userInfo: ["screen": screenType])
}
}
}
5. Обработка фоновых обновлений (iOS 7+)
Для silent push notifications:
extension AppDelegate {
func application(_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable: Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
// Проверка на silent notification
if let aps = userInfo["aps"] as? [String: Any],
aps["content-available"] as? Int == 1 {
// Фоновая обработка данных
processBackgroundData(userInfo)
// Обновление интерфейса через NotificationCenter
NotificationCenter.default.post(name: NSNotification.Name("DataUpdated"),
object: nil,
userInfo: userInfo)
completionHandler(.newData)
} else {
completionHandler(.noData)
}
}
private func processBackgroundData(_ userInfo: [AnyHashable: Any]) {
// Логика обработки данных в фоне
print("Фоновая обработка данных: \(userInfo)")
}
}
6. Современный подход с AppDelegate и SceneDelegate
Для приложений с поддержкой сцен:
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
func scene(_ scene: UIScene,
willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions) {
// Обработка уведомления при запуске
if let notificationResponse = connectionOptions.notificationResponse {
handleNotification(response: notificationResponse)
}
}
func sceneDidBecomeActive(_ scene: UIScene) {
// Очистка бейджа при активации сцены
UIApplication.shared.applicationIconBadgeNumber = 0
}
private func handleNotification(response: UNNotificationResponse) {
// Навигация по deep link из уведомления
}
}
7. Дополнительные настройки для расширенных функций
Notification Service Extension (для модификации уведомлений):
// Создать новый target: Notification Service Extension
import UserNotifications
class NotificationService: UNNotificationServiceExtension {
override func didReceive(_ request: UNNotificationRequest,
withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
// Модификация контента уведомления
let bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
if let bestAttemptContent = bestAttemptContent {
// Добавление медиа или изменение текста
bestAttemptContent.title = "\(bestAttemptContent.title) [Модифицировано]"
bestAttemptContent.sound = UNNotificationSound.default
contentHandler(bestAttemptContent)
}
}
}
Ключевые моменты для корректной работы:
- Разрешения пользователя — всегда запрашивать авторизацию асинхронно
- Проверка токена — устройство может менять токен после переустановки приложения
- Фоновая обработка — использовать
content-available: 1для silent push - Тестирование — использовать такие инструменты как Pusher или собственный сервер для отладки
- Обработка состояний — учитывать, что приложение может быть в фоне, свернуто или закрыто
Пример полезной утилиты для работы с уведомлениями:
class NotificationManager {
static let shared = NotificationManager()
func checkNotificationSettings(completion: @escaping (Bool) -> Void) {
UNUserNotificationCenter.current().getNotificationSettings { settings in
DispatchQueue.main.async {
let isAuthorized = settings.authorizationStatus == .authorized
completion(isAuthorized)
}
}
}
func updateBadge(count: Int) {
UIApplication.shared.applicationIconBadgeNumber = count
}
func removeAllDeliveredNotifications() {
UNUserNotificationCenter.current().removeAllDeliveredNotifications()
}
}
Этот комплексный подход обеспечивает полную поддержку push-уведомлений с учетом всех современных требований iOS и лучших практик разработки.