Ответ
Интеграция push-уведомлений (Remote Notifications) в iOS требует настройки как на стороне приложения, так и на сервере, а также взаимодействия с сервисом Apple Push Notification service (APNs).
Основные шаги реализации:
-
Настройка проекта:
- В Apple Developer Account включите Push Notifications для App ID.
- В Xcode добавьте capability "Push Notifications" и "Background Modes" (опционально, для фоновых уведомлений).
- Сгенерируйте и загрузите сертификат или ключ (Auth Key) для APNs в личном кабинете разработчика.
-
Запрос разрешения у пользователя (обязательный шаг): Используйте
UNUserNotificationCenter. Запрос должен быть контекстуальным.import UserNotifications let center = UNUserNotificationCenter.current() center.requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in if granted { print("Permission granted.") // Регистрация для remote-уведомлений должна выполняться в главном потоке DispatchQueue.main.async { UIApplication.shared.registerForRemoteNotifications() } } else { print("Permission denied.") } } -
Регистрация устройства в APNs и получение токена: Система автоматически связывается с APNs. Токен устройства уникален для комбинации "приложение + устройство" и может меняться.
// Успешная регистрация (AppDelegate или SceneDelegate) func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { // Конвертируем Data в строку (формат может быть нужен для вашего сервера) let tokenString = deviceToken.map { String(format: "%02.2hhx", $0) }.joined() print("APNs Device Token: (tokenString)") // ОТПРАВЬТЕ этот токен на ваш backend-сервер. } // Ошибка регистрации func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { print("Failed to register for remote notifications: (error)") } -
Обработка входящего уведомления: Для iOS 10+ реализуйте
UNUserNotificationCenterDelegate.// Уведомление получено, когда приложение на переднем плане func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { // Решаем, как показать уведомление (.banner, .sound, .badge) completionHandler([.banner, .sound]) } // Пользователь тапнул по уведомлению func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { let userInfo = response.notification.request.content.userInfo // Извлеките данные и выполните навигацию в приложении completionHandler() }
Ключевой момент: Ваш сервер должен хранить токены устройств и использовать APNs API (или библиотеку) для отправки уведомлений на конкретные токены.
Ответ 18+ 🔞
Да ты посмотри, какая хуйня, блядь! Эти пуш-уведомления в iOS — это ж целая эпопея, ёпта! Надо и в приложении ковыряться, и сервер свой настраивать, и ещё с этой шайтан-службой Apple (APNs) договориться. Ну, пиздец, короче. Сейчас разжуем, как это проглотить, чтобы не подавиться.
Что тебе делать, чтобы эта штука заработала:
-
Настройка проекта — тут без вариантов:
- Заваливаешься в Apple Developer Account, находишь свой App ID и включаешь там галочку «Push Notifications». Без этого нихуя не полетит.
- В Xcode открываешь настройки таргета и тыкаешь «+ Capability». Добавляешь «Push Notifications». Если хочешь, чтобы уведомления и в фоне работали, добавь ещё «Background Modes» и отметь «Remote notifications». Но это уже по желанию, блядь.
- Теперь самое весёлое: сертификаты. Иди обратно в личный кабинет разработчика, генерируй либо сертификат (старая школа), либо ключ (Auth Key, новая школа) специально для APNs. Этот файл — твой пропускной билет. Без него твой сервер будет как слепой крот — тыкаться лбом в стену.
-
Спросить у юзера разрешение (это ОБЯЗАТЕЛЬНО, иначе пиши пропало): Используй
UNUserNotificationCenter. И спрашивай не абы когда, а в подходящий момент, а то пользователь тебе просто посылает нахуй.import UserNotifications let center = UNUserNotificationCenter.current() center.requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in if granted { print("Разрешил, ура!") // Регистрацию для пуша делай в главном потоке, не выёбывайся DispatchQueue.main.async { UIApplication.shared.registerForRemoteNotifications() } } else { print("Отказал, пидорас... Ну или просто осторожный.") } } -
Регистрация устройства и получение токена (это магия системы): Как только ты вызвал
registerForRemoteNotifications(), система сама, тихо и незаметно, связывается с серверами Apple. Твоя задача — поймать ответ.// Всё прошло хорошо (пиши в AppDelegate или SceneDelegate) func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { // Токен приходит в виде Data, а серверу нужна строка. Конвертируем, блядь. let tokenString = deviceToken.map { String(format: "%02.2hhx", $0) }.joined() print("APNs Device Token: (tokenString)") // Смотри, не обосрись, это ценный ключ! // СРОЧНО шли этот токен на свой бэкенд! Запоминай, сохраняй, передавай. Это твой билет. } // Всё пошло по пизде (такое тоже бывает) func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { print("Не удалось зарегистрироваться для пуша, вот ошибка: (error)") // Проверь симулятор (там это не работает), проверь профили, проверь всё, блядь! }Запомни: этот токен — уникальная штука для связки «твоё приложение + конкретное устройство». И он может внезапно поменяться! Так что на сервере будь готов его обновлять.
-
Обработка уведомления, когда оно уже прилетело: Для iOS 10 и выше работаем через
UNUserNotificationCenterDelegate. Вешаем его на центр и ловим события.// Уведомление пришло, когда приложение открыто и на экране func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { // Решаем, как его показать: баннером, со звуком, с бейджем? completionHandler([.banner, .sound]) // Например, так } // Пользователь тапнул по уведомлению, чтобы открыть приложение func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { let userInfo = response.notification.request.content.userInfo // Вот тут в userInfo лежат твои кастомные данные. Выковыривай их и веди пользователя куда нужно в приложении. completionHandler() // Всегда вызывай в конце, система ждёт }
Самый главный пункт, блядь: Твой сервер должен быть умным. Он обязан хранить все эти device token'ы, как зеницу ока. А когда захочет что-то сказать пользователю — брать нужный токен и через APNs API (или какую-нибудь готовую библиотеку) слать на него своё послание. Вот и вся магия, ёпта!