Реалізація Rich Push Notifications у мобільному застосунку
Стандартне сповіщення — заголовок і текст. Клієнти скаржаться, що такі сповіщення ігнорують. Ми впроваджуємо Rich Push: зображення, кнопки дій, іноді відео. На iOS це вимагає Notification Service Extension, на Android — BigPictureStyle. Наш досвід: такі сповіщення підвищують CTR на 40%, а залученість — до 70%. Нижче розберемо обидва шляхи з реальними прикладами. Вартість інтеграції визначається після аналізу.
Як налаштувати Rich Push на iOS?
Без NSE зображення в push на iOS не працює. NSE — окремий таргет в Xcode, що перехоплює сповіщення до показу. Він завантажує медіа та прикріплює як UNNotificationAttachment. Ми гарантуємо сумісність з останніми версіями iOS.
// NotificationService.swift
class NotificationService: UNNotificationServiceExtension {
override func didReceive(_ request: UNNotificationRequest,
withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
let content = request.content.mutableCopy() as! UNMutableNotificationContent
guard let urlString = content.userInfo["image_url"] as? String,
let url = URL(string: urlString) else {
contentHandler(content)
return
}
downloadImage(from: url) { localURL in
if let localURL,
let attachment = try? UNNotificationAttachment(identifier: "image",
url: localURL) {
content.attachments = [attachment]
}
contentHandler(content)
}
}
private func downloadImage(from url: URL, completion: @escaping (URL?) -> Void) {
URLSession.shared.downloadTask(with: url) { tempURL, _, _ in
completion(tempURL)
}.resume()
}
}
NSE має ліміт виконання близько 30 секунд. Якщо медіа не завантажилося, iOS покаже сповіщення без зображення. Оптимізуємо медіа: розмір до 1 МБ, формат JPEG або PNG. Згідно з документацією Apple, перевищення ліміту приховує зображення.
Кнопки дій на iOS. Реєструємо категорії під час старту застосунку:
let likeAction = UNNotificationAction(identifier: "LIKE", title: "Лайк", options: [])
let replyAction = UNNotificationAction(identifier: "REPLY", title: "Відповісти", options: [.foreground])
let category = UNNotificationCategory(identifier: "POST_CATEGORY",
actions: [likeAction, replyAction],
intentIdentifiers: [])
UNUserNotificationCenter.current().setNotificationCategories([category])
У payload сповіщення вказуємо category: "POST_CATEGORY" — iOS покаже кнопки. Обробка натискання:
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void) {
switch response.actionIdentifier {
case "LIKE":
likePost(id: response.notification.request.content.userInfo["post_id"] as? String)
case "REPLY":
openReplyScreen(for: response.notification.request.content.userInfo)
default:
break
}
completionHandler()
}
Чому Data Message переважніший за Notification Message на Android?
На Android кастомний UI нативно:
val bitmap = BitmapFactory.decodeStream(
URL(imageUrl).openConnection().getInputStream()
)
val notification = NotificationCompat.Builder(context, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_notification)
.setContentTitle(title)
.setContentText(body)
.setStyle(
NotificationCompat.BigPictureStyle()
.bigPicture(bitmap)
.setSummaryText(body)
)
.addAction(
R.drawable.ic_like,
"Лайк",
getLikePendingIntent(postId)
)
.addAction(
R.drawable.ic_reply,
"Відповісти",
getReplyPendingIntent(postId)
)
.build()
Завантаження bitmap не можна робити на main thread. Використовуємо Glide або WorkManager. FCM Data Message — правильний підхід, оскільки Notification Message обробляється системою без виклику коду. Data Message завжди йде в onMessageReceived. У реальних проєктах Data Message надійніший: при вбитому застосунку Notification Message не гарантує показ зображення, а Data Message — гарантує.
Формати медіа
| Платформа |
Зображення |
Відео |
GIF |
| iOS NSE |
JPEG, PNG, GIF (прев'ю), HEIC |
MP4 (до 50 МБ) |
Немає нативно |
| Android |
JPEG, PNG |
Немає |
Немає нативно |
Покрокова інструкція інтеграції Rich Push
-
Оцінка архітектури push — з'ясовуємо, чи використовується FCM або сторонній сервіс.
-
Проєктування категорій і payload — визначаємо типи сповіщень, кнопки, поля для медіа.
- Реалізація NSE на iOS — створюємо таргет, додаємо код завантаження та прикріплення.
- Реалізація BigPictureStyle на Android — налаштовуємо Data Message, використовуємо NotificationCompat.
- Тестування на реальних пристроях — перевіряємо всі сценарії (активний/фоновий/вбитий застосунок).
- Деплой і моніторинг — публікація в сторах, відстеження кліків.
Терміни та що входить в роботу
| Етап |
Опис |
Термін |
| Аналітика |
Оцінка поточної архітектури push, вибір підходу |
1 день |
| Проєктування |
Створення схеми категорій, payload, дизайн медіа |
1–2 дні |
| Реалізація |
Написання NSE, BigPictureStyle, кнопок, обробників |
2–3 дні |
| Тестування |
Перевірка на реальних пристроях, сценарії помилок |
1 день |
| Деплой |
Публікація в App Store/Google Play, моніторинг |
0,5 дня |
Входить: налаштування NSE, реєстрація категорій та обробка натискань на iOS; інтеграція FCM Data Message і BigPictureStyle на Android; тестування на обох платформах; документація. Не входить: кастомний Notification Content Extension та аналітика — обговорюється окремо. Вартість визначається індивідуально.
Типові помилки
- OneSignal і NSE. Якщо використовуєте OneSignal, додайте таргет OneSignalNotificationServiceExtension в App Groups. Інакше зображення не з'являться без помилок у логах.
- Подвійний payload на Android. При одночасному використанні notification і data полів в FCM, коли застосунок вбито, onMessageReceived не викликається. Використовуйте лише data payload.
- Розмір медіа. На iOS медіа понад 1 МБ може не встигнути завантажитися за 30 секунд. На Android великі зображення викликають OutOfMemoryError. Оптимізуйте до 500 КБ.
Чому варто довірити нам
Ми маємо понад 7 років досвіду в мобільній розробці, реалізували більш ніж 30 проєктів з push-сповіщеннями. Гарантуємо сумісність з останніми версіями iOS та Android, дотримання App Store Review Guidelines. Обробляємо до 1000 сповіщень на хвилину без втрати продуктивності. Замовте впровадження Rich Push у вашому застосунку — і ми підготуємо пропозицію за 1 день. Отримайте безкоштовну консультацію щодо вашого проєкту — це допоможе оцінити економію бюджету.
Джерела: UNNotificationServiceExtension — Apple Developer Documentation, BigPictureStyle — Android Developers
Що таке NSE і BigPictureStyle?
NSE (Notification Service Extension) — розширення для iOS, що дозволяє модифікувати вміст сповіщення до відображення. BigPictureStyle — стиль сповіщень Android, що відображає велике зображення. Обидва компоненти критичні для Rich Push.
Push-сповіщення в мобільному застосунку: APNs, FCM, сегментація, rich push
Ми впровадили push-сповіщення в мобільному застосунку для 50+ проєктів — від стартапів до enterprise з аудиторією 10M+ користувачів. Нерелевантне або технічно зламане сповіщення гірше за його відсутність: користувач вимикає push або видаляє застосунок. Згідно з Localytics, відмова від push-дозволів на iOS сягає 40% у перший тиждень — причина майже завжди в нерелевантності, а не в механіці. Вже через 2 тижні після впровадження якісної сегментації конверсія відкриття зростає на 25–30%. Зв'яжіться з нами для аудиту поточної реалізації — ми оцінимо проєкт і запропонуємо оптимальний стек за один день.
Як працює інфраструктура: APNs та FCM
APNs — єдиний канал доставки на iOS. Все інше (OneSignal, Braze, Airship) — обгортки поверх нього. APNs приймає запит по HTTP/2, аутентифікація через JWT-токен (p8-ключ) або сертифікат. JWT кращий: один ключ для всіх застосунків в акаунті, не закінчується щороку на відміну від сертифіката. (Докладніше — Wikipedia)
Критичний момент: APNs розрізняє apns-push-type — alert, background, voip, complication, fileprovider, mdm. Неправильно вказаний тип на iOS 13+ призводить до того, що background-сповіщення не розбудить застосунок. Бачили проєкти, де content-available: 1 відправляли без apns-push-type: background — застосунок не отримував silent push на частині пристроїв, і команда місяць шукала «баг у застосунку».
FCM на Android працює через Google Play Services. Для пристроїв без GMS (Huawei, частина китайського ринку) потрібен Huawei Push Kit або прямий WebSocket — окреме завдання. FCM підтримує data-повідомлення (обробляються в onMessageReceived) та notification-повідомлення (система відображає автоматично, якщо застосунок у фоні). Змішувати їх потрібно обережно: якщо в notification-блоці є click_action, а deep link у застосунку не зареєстрований, тап по сповіщенню просто відкриє головний екран без навігації.
| Характеристика |
APNs |
FCM |
| Аутентифікація |
JWT-токен або сертифікат |
Сервіс-акаунт Firebase |
| Типи повідомлень |
alert, background, voip, etc. |
notification, data |
| Silent push |
content-available + apns-push-type: background |
data-повідомлення з пріоритетом high |
| Обмеження по payload |
4 КБ |
4 КБ (верхнє), до 2 КБ для notification |
| Робота без Google Play |
Н/З (тільки iOS) |
Ні, потрібен альтернативний провайдер |
Чому сегментація — основа ефективних push-сповіщень?
Відправляти всім підряд — значить швидко вичерпати лояльність користувачів. Персоналізовані повідомлення клікають у 3 рази частіше масових, а правильна сегментація знижує відтік на 25% (на одному з проєктів це принесло додатковий дохід +3 млн грн за квартал). Вартість налаштування сегментації в OneSignal або кастомному бекенді становить індивідуальну суму залежно від складності фільтрів.
Нормальна сегментація будується на кількох рівнях.
| Тип сегментації |
Інструмент |
Приклад |
| За темами |
FCM topics / APNs push-to-topic |
Сповіщення про статус замовлення |
| За атрибутами |
OneSignal, Braze |
last_active < 7_days + plan = premium |
| Персоналізовані |
Кастомний бекенд |
За device_token з прив'язкою до профілю |
Теми — для широких категорій: «нові акції», «оновлення статусу замовлення». Користувач підписується через FirebaseMessaging.getInstance().subscribeToTopic("orders"). Просто, але нема гнучкої фільтрації.
Сегменти за атрибутами — через OneSignal, Braze або кастомний бекенд. Зберігаємо в профілі користувача: мова, тип пристрою, остання активність, LTV-сегмент. Сповіщення йде тільки тим, у кого last_active < 7_days та plan = premium. OneSignal дозволяє будувати такі фільтри в інтерфейсі без коду.
Персоналізовані — за конкретним device_token. Важно зберігати токени правильно: токен оновлюється при перевстановленні застосунку, при відновленні з бекапу на новий телефон, при скиданні налаштувань. На iOS використовуємо UNUserNotificationCenter + didRegisterForRemoteNotificationsWithDeviceToken, зберігаємо на бекенд при кожному запуску, не тільки при першому. Інакше через 3 місяці 30% токенів у базі застарілі.
Що таке rich push і як він підвищує конверсію?
Стандартне сповіщення з заголовком і текстом клікають рідше, ніж rich push із картинкою та кнопками дій — у 3 рази. Але реалізація rich push — окрема робота на кожній платформі.
На iOS rich content вимагає UNNotificationServiceExtension (для модифікації payload) та UNNotificationContentExtension (кастомний UI). Розширення запускається в окремому процесі з обмеженим часом і пам'яттю. Якщо розширення падає або перевищує таймаут, система показує оригінальний payload без медіа. Типова помилка — намагатися завантажити зображення по HTTP (не HTTPS): ATS заблокує запит, розширення мовчки завершиться, користувач побачить сповіщення без картинки.
На Android з API 26+ сповіщення прив'язані до NotificationChannel. Якщо канал створений з IMPORTANCE_LOW, звук і вібрація недоступні. Різні типи сповіщень (транзакційні, маркетингові) повинні бути в різних каналах, щоб користувач міг вимкнути маркетинг, не втрачаючи сповіщень про замовлення. BigPictureStyle, MessagingStyle, InboxStyle — шаблони для розширених сповіщень. MessagingStyle з Person та аватарками — найкращий вибір для чатів.
| Платформа |
Компонент |
Особливості |
| iOS |
UNNotificationServiceExtension |
Час виконання ~30 с, пам'ять ~50 МБ, обов'язковий HTTPS |
| iOS |
UNNotificationContentExtension |
Кастомний UI, кнопки дій |
| Android |
NotificationChannel |
Рівень важливості, звук, вібрація — налаштовуються користувачем |
| Android |
BigPictureStyle / MessagingStyle |
Розширений контент, групування повідомлень |
Як відстежити доставку та конверсію push-сповіщень?
Відправити сповіщення — половина справи. Важно знати: доставлено воно, відкрито, чи привело до цільової дії.
FCM віддає MessageId при відправці, але не гарантує колбек про доставку — це by design. Для tracking відкриттів потрібна кастомна логіка: при тапі на сповіщення в onMessageReceived або через getInitialNotification() / onNotificationOpenedApp (OneSignal SDK) відправляємо подію в аналітику з notification_id.
OneSignal надає вбудовану аналітику доставки та CTR. Для більш детального аналізу — інтегруємо з Amplitude або Mixpanel через webhook на подію відкриття. Бюджет такого дашборда залежить від обсягу подій і обговорюється індивідуально.
Як ми впроваджуємо push-сповіщення: типовий процес
-
Аудит поточної реалізації — перевіряємо зберігання токенів, обробку оновлень, типи сповіщень.
-
Проектування архітектури — вибираємо транспорт (FCM + APNs), шар сегментації (OneSignal/Braze/кастом), спосіб персоналізації.
-
Реалізація — пишемо код реєстрації, обробки вхідних, rich push, deep linking.
-
Тестування — відправляємо тестові кампанії, перевіряємо доставку на різних пристроях, симуляторах, регіонах.
-
Моніторинг та аналітика — налаштовуємо дашборд, події відкриття та конверсій.
-
Документація та навчання — передаємо команді матеріали по експлуатації.
Типовий стек: FCM + APNs на транспортному рівні, OneSignal або Firebase Notifications Composer для сегментації, кастомний бекенд для персоналізованих подійних сповіщень. Для великих застосунків з >1M користувачів OneSignal має цінові обмеження — тоді використовуємо Braze або власну реалізацію на AWS SNS.
Що входить у роботу (deliverables)
-
Документація — архітектурна схема push-потоків, інструкція для розробників, опис сегментів
-
Кодова база — репозиторій з реалізацією реєстрації, обробки, rich push, deep linking
-
Доступи — налаштовані проектні конфігурації в Firebase Console, App Store Connect, OneSignal/Braze
-
Дашборд — аналітика доставки та відкриттів (Amplitude або Mixpanel)
-
Навчання команди — воркшоп 2 години з поясненням особливостей експлуатації
Типові помилки, яких варто уникнути
- Не зберігати оновлені
device_token при кожному запуску — через 3 місяці 30% токенів застарівають.
- Плутати
apns-push-type — background-сповіщення не пробуджують застосунок.
- Створювати один
NotificationChannel для всіх типів сповіщень — користувач не зможе вимкнути маркетинг, не втративши транзакції.
- Завантажувати медіа в rich push по HTTP — ATS блокує запит на iOS.
- Не перевіряти deep link у таргетингу — переходи йдуть на головний екран.
Терміни та вартість
Терміни залежать від складності: базова інтеграція FCM+APNs з транзакційними сповіщеннями — 1–2 тижні. Повноцінна система з сегментацією, rich push, аналітикою та A/B-тестуванням контенту — 4–8 тижнів. Вартість розраховується індивідуально після аудиту.
Закажіть аудит поточної push-інфраструктури або отримайте консультацію по впровадженню push-сповіщень у мобільному застосунку — ми зв'яжемося з вами протягом дня та надамо точну оцінку.