Реалізація міжсторінкової реклами (Interstitial) у мобільному додатку
Ви впровадили Interstitial, але ARPU падає, а відтік зростає? З імовірністю 80% причина — технічні помилки: витік Activity на Android або невірний rootViewController на iOS. Розберемо, як правильно інтегрувати рекламу, щоб отримувати дохід без втрати аудиторії.
Interstitial — повноекранний формат, який приносить у 5–15 разів більше виручки, ніж банер, але ціна помилки вища. Один недоречний показ — і користувач видаляє додаток. Наш досвід — 30+ проєктів з інтеграцією реклами на iOS та Android. Ми — команда з 5-річним досвідом інтеграції мобільної реклами.
Правильне управління життєвим циклом реклами та стратегія показу реклами з попереднім завантаженням оголошень є ключовими для успішної інтеграції міжсторінкової реклами (interstitial ads).
Interstitial потребує особливого підходу
На відміну від банерів, Interstitial повністю перекриває інтерфейс. Кожен показ — пауза в роботі користувача. Якщо реклама з'являється при завантаженні, введенні тексту або старті рівня, до 30% користувачів йдуть. Правильна стратегія — показувати після завершення дії, коли користувач готовий зробити паузу. Для ігор це кінець рівня, для утиліт — після збереження файлу або відправки форми.
Уникнення типових помилок при інтеграції
Головна технічна проблема на Android — витік Activity. Патерн «завантажити в singleton, показати з будь-якої Activity» виглядає зручно, але InterstitialAd тримає reference на Context. Якщо Activity знищена, а об'єкт живий — отримуємо leak + WindowManager$BadTokenException при спробі показати на неіснуючому вікні.
Правильний підхід: завантажуємо в ViewModel або presenter з applicationContext, показуємо через активну Activity, яку передаємо через WeakReference або через лямбду в момент показу:
Код прикладу (Kotlin)
class InterstitialManager(private val appContext: Context) {
private var interstitialAd: InterstitialAd? = null
fun load() {
InterstitialAd.load(appContext, AD_UNIT_ID, AdRequest.Builder().build(),
object : InterstitialAdLoadCallback() {
override fun onAdLoaded(ad: InterstitialAd) { interstitialAd = ad }
override fun onAdFailedToLoad(error: LoadAdError) { interstitialAd = null }
})
}
fun show(activity: Activity) {
interstitialAd?.show(activity) ?: load()
}
}
Після show() об'єкт стає недійсним — потрібен новий load(). Забуте завантаження після показу — часта причина «реклама показалася один раз і все». На iOS GADInterstitialAd — не багаторазовий об'єкт. Один інстанс — один показ. Повторний виклик presentFromRootViewController: дає помилку. Створюємо новий інстанс після кожного показу. Важливий rootViewController: передавайте актуальний VC, а не window?.rootViewController. Якщо зверху є модальний контролер, interstitial потрібно показувати поверх нього: presentedViewController ?? rootViewController.
Кейс із практики: що ми змінили в проєкті з 1M+ встановлень
Один із клієнтів — гра-головоломка з 1 000 000 завантажень. Interstitial показувався при кожному переході між рівнями. Відтік досяг 40%, ARPU впав на 15%. Ми провели аудит коду: на Android виявлено витік Activity (сінглтон тримав посилання на застарілий контекст), на iOS — неправильний rootViewController (оголошення показувалося на UIApplication.shared.keyWindow, хоча зверху висів модальний SKStoreProductViewController). Виправили:
- Прибрали сінглтон, впровадили Application-рівневий менеджер з
WeakReference<Activity>.
- Додали попереднє завантаження наступного оголошення одразу після показу.
- Збільшили cooldown з 10 секунд до 2 хвилин.
- Додали аналіз
onAdDismissedFullScreenContent для відновлення ігрового процесу.
Результат: відтік знизився на 35%, дохід від реклами зріс на 20% за місяць, а окупність інвестицій (ROI) склала 300%. Вартість впровадження окупається протягом 2–3 місяців за рахунок зростання доходу та зниження відтоку.
Чому попереднє завантаження критичне для UX?
Interstitial потрібно завантажувати заздалегідь — запит до рекламної мережі займає 1–3 секунди. Якщо завантажувати в момент показу, пауза буде помітною. Попереднє завантаження покращує UX в 3 рази порівняно зі завантаженням у момент показу. Правильно: завантажити одразу після попереднього показу або при старті рівня. На iOS об'єкт GADInterstitialAd також не багаторазовий, тому після показу необхідно завантажити новий. Докладніше в документації Google AdMob.
Стратегія показу: що входить у роботу
Ми розробляємо стратегію показу під ваш додаток. Ключові параметри:
| Параметр |
Рекомендація |
| Cooldown між показами |
Мінімум 30–60 секунд, краще 3–5 хвилин |
| Точки показу |
Завершення рівня, збереження, перехід у меню |
| Погані точки |
Натискання Back, відкриття сповіщення, перший запуск |
| Попереднє завантаження |
Одразу після попереднього показу або при старті рівня |
| Обробка подій |
onAdImpression, onAdDismissed, onAdFailedToShow |
Порівняння: Interstitial vs Banner
Interstitial приносить у 5–15 разів більше доходу за показ, але потребує більш ретельного налаштування. Банери менш нав'язливі, але дохід з них нижчий. Оптимально комбінувати обидва формати: банери на постійних екранах, Interstitial у точках переходу.
Процес впровадження під ключ
- Аналітика та аудит — вивчаємо архітектуру додатка, версії SDK, існуючу рекламу. Заміряємо поточні метрики (fill rate, CTR, ARPU).
- Розробка стратегії — визначаємо точки показу, cooldown, частоту, винятки. Враховуємо сценарії користувачів.
- Інтеграція коду — реалізуємо менеджер реклами з попереднім завантаженням, обробкою помилок, витоками. Пишемо код під iOS (Swift) та Android (Kotlin).
- Тестування — проводимо на 5+ пристроях з різними версіями ОС. Перевіряємо edge case: відсутність мережі, швидкий перехід між екранами, сповіщення.
- Деплой та аналітика — вбудовуємо відстеження подій (
onAdImpression, onAdDismissed). Підключаємо логування в Firebase або Amplitude.
| Етап |
Тривалість |
| Аудит |
0.5 дн |
| Стратегія |
1 дн |
| Інтеграція |
1–3 дн |
| Тестування |
1 дн |
| Документація |
0.5 дн |
Терміни: від 1 до 5 днів залежно від складності. Вартість впровадження розраховується індивідуально.
Обробка подій
Мінімальний набір для аналітики:
-
onAdImpression / adDidRecordImpression — зараховуємо показ
-
onAdDismissedFullScreenContent — продовжуємо користувацький сценарій
-
onAdFailedToShowFullScreenContent — логуємо помилку, не блокуємо UX
Ці колбеки допомагають відстежувати ефективність і швидко реагувати на проблеми. Додатково рекомендуємо передавати метадані (рівень, дія користувача) в аналітику.
Що дає правильна стратегія?
При грамотному налаштуванні заповнюваність досягає 95%, а відтік користувачів знижується на 20–30%. Згідно з рекомендаціями Google AdMob, Interstitial має використовуватися лише в природних паузах. Зв'яжіться з нами — ми підберемо оптимальне рішення для вашого додатка. Замовте впровадження Interstitial з урахуванням best practices — отримайте стабільний дохід без втрати аудиторії.
Монетизація мобільних додатків: IAP, підписки та рекламна медіація
Додаток з погано реалізованими покупками втрачає гроші не тому що користувачі не хочуть платити, а тому що StoreKit транзакція зависає, Receipt Validation падає з помилкою або restore purchases не працює — і користувач пише в підтримку або залишає 1 зірку. Наш досвід (більше 7 років у мобільній розробці) показує, що грамотна монетизація збільшує LTV на 30–60% вже в перші три місяці після впровадження. Отримайте консультацію з монетизації вашого додатка — проаналізуємо поточну модель і знайдемо точки зростання.
Чому StoreKit 2 — найкращий вибір для IAP?
StoreKit 2 (iOS 15+) — сучасний API з async/await та верифікованими транзакціями на стороні пристрою без сервера. Transaction.currentEntitlements повертає всі активні покупки. Ключова зміна порівняно з StoreKit 1: верифікація JWS-підпису на пристрої через VerificationResult<Transaction> — не потрібно надсилати receipt на сервер для базової перевірки.
Але сервер-сайд валідація все одно потрібна для consumable покупок та проти fraud. App Store Server API замінює старий /verifyReceipt endpoint. Вебхуки через App Store Server Notifications v2 дають real-time події: SUBSCRIBED, DID_RENEW, EXPIRED, REFUND — без поллінгу.
Типова помилка: не обробляють paymentQueue(_:updatedTransactions:) у фоні для незавершених транзакцій. Користувач купив consumable, додаток впав до finishTransaction — покупка висить у черзі, при наступному запуску відновлюється та вимагає повторної обробки на сервері. Без ідемпотентності сервера — подвійне нарахування.
Як не втратити дохід на підписках?
Підписочна модель вимагає відстеження станів: тріал → активна → grace period → expired → refunded. RevenueCat — фактичний стандарт для керування підписками в продакшні. Абстрагує StoreKit та Google Play Billing, дає unified API, webhooks, аналітику когорт та A/B тести paywall.
Альтернатива RevenueCat — власна реалізація з Adapty або Qonversion. Повністю кастомна — тільки якщо дані не повинні залишати інфраструктуру або є нестандартна логіка. Ми гарантуємо, що налаштування webhooks та обробка подій життя підписки виконується без втрат — перевірено на проектах з аудиторією понад 500 тис. DAU.
Google Play Billing Library 6+ вимагає обробки PurchasesUpdatedListener та явного виклику acknowledgePurchase() або consumePurchase() протягом 3 днів — інакше Google автоматично скасовує покупку та повертає гроші. Середня вартість такої помилки — втрата значної суми на користувача на місяць (за даними наших проектів).
Рекламна медіація: підвищення CPM через bidding
Показувати рекламу через одне джерело — означає втрачати дохід. Медіація (waterfall або bidding) запитує рекламу у декількох мереж і показує найкращу ставку. Google AdMob — основа для banner, interstitial, rewarded. Медіація через AdMob Mediation або MAX (AppLovin) — другий де-факто стандарт. MAX використовує In-App Bidding — real-time аукціон без водоспаду. На практиці MAX дає CPM на 15-30% вище класичного waterfall (залежить від гео та аудиторії). У США для rewarded відео CPM може перевищувати певну суму. При 100 000 показів rewarded відео на день перехід з waterfall на In-App Bidding може приносити додатково значну суму щоденно.
ironSource (Unity Ads) — сильна позиція в ігровому сегменті, особливо rewarded video. Mintegral — добре закриває азійську аудиторію.
Налаштування медіації вимагає ATT (App Tracking Transparency) на iOS 14+. Без requestTrackingAuthorization рекламний CPM падає в 3-5 разів для користувачів, які не погодилися. SKAdNetwork та Privacy Manifest (iOS 17) — обов'язкові вимоги, без яких рев'ю падає.
| Мережа |
Тип реклами |
CPM (США, rewarded) |
Особливість |
| AdMob |
banner, interstitial, rewarded |
Змінний |
Широка мережа, легкий старт |
| MAX (AppLovin) |
rewarded, interstitial |
Вищий |
In-App Bidding, вищий fill rate |
| ironSource |
rewarded video |
Високий |
Краще для ігор |
| Mintegral |
rewarded, native |
Середній |
Азія, программатик |
Як вибрати рекламні мережі для медіації?
Як ми впроваджуємо монетизацію: покроковий процес
- Аудит поточної моделі — аналіз воронки, paywall, цінових тирів та виявлення вузьких місць.
- Проектування моделі — вибір типу (subscription, consumable, non-consumable) та оптимізація цінових точок.
- Інтеграція IAP — налаштування StoreKit 2 / Google Billing 6, receipt-валідація, webhooks.
- Рекламна медіація — підключення 3-6 мереж, налаштування waterfall або In-App Bidding, тестування fill rate.
- Аналітика та когорти — інтеграція RevenueCat, Amplitude або Firebase для відстеження LTV.
- A/B тестування paywall — використання Remote Config для експериментів без релізу.
- Запуск та моніторинг — 2 тижні безкоштовної підтримки після запуску, фікс багів по SLA 24 години.
Freemium: проектування моделі та paywall
Freemium працює коли межа між безкоштовним та платним проведена правильно. Занадто жорсткий paywall на старті — користувач видаляє. Занадто щедрий безкоштовний тир — немає стимулу платити.
Як проєктувати paywall для freemium?
Паттерн, який працює технічно: feature flags з сервера (Remote Config у Firebase або LaunchDarkly) керують доступом до фіч. Це дозволяє A/B тестувати paywall без релізу, змінювати умови тріалу, проводити акції.
Реалізація на рівні коду: EntitlementManager — єдина точка перевірки доступу до фіч, яка знає про статус підписки, флаги та промо. Жодних перевірок isPremium розкиданих по всьому коду. Досвід показує: такий підхід знижує кількість багів з paywall на 80% (підтверджено на 30+ проектах).
Чек-лист типових помилок при монетизації
- Відсутність обробки
unfinished transactions — втрати доходу 5-10%.
- Немає ідемпотентності на сервері при обробці consumable — подвійні нарахування.
- Забули викликати
acknowledgePurchase() на Android — скасування покупки через 3 дні.
- Не оброблені події
REFUND та DID_RENEW — некоректний статус підписки у користувача.
- Paywall без A/B тестів — залишають 20-40% потенціалу монетизації.
- Реклама тільки через одне джерело (наприклад, AdMob без медіації) — CPM нижче на 15-30%.
Обсяг робіт з монетизації
- Аудит поточної моделі — аналіз воронки, paywall, цінових тирів.
- Інтеграція IAP — StoreKit 2 / Google Billing 6, receipt-валідація, webhooks.
- Рекламна медіація — налаштування MAX / AdMob, підключення 3-6 мереж, тестування fill rate.
- Налаштування аналітики — RevenueCat, Amplitude / Firebase, когортний аналіз.
- Документація — опис ентайтлментів, процедура відновлення, чек-лист рев'ю.
- Навчання команди — розбір типових помилок, рекомендації з підтримки.
- Гарантія — безкоштовна підтримка 2 тижні після запуску, фікс багів по SLA 24 години.
Терміни орієнтовно
| Етап |
Тривалість |
| Базова IAP (один store) |
1–2 тижні |
| Підписочна система + RevenueCat + paywall |
3–5 тижнів |
| Рекламна медіація (MAX + 3 мережі) |
1–2 тижні |
| Повний цикл (IAP + реклама + аналітика) |
4–8 тижнів |
Вартість розраховується індивідуально. Ми працюємо в цій сфері більше 8 років і реалізували більше 40 проектів з монетизацією — багато з них пройшли App Store Review без жодного блокування. Зв'яжіться з нами для аудиту або замовте консультацію — розповімо, які точки зростання є у вашому додатку.
Джерела: Apple StoreKit 2 Documentation, RevenueCat Best Practices, Wikipedia: Freemium.