Впровадження App Tracking Transparency (ATT) для iOS
Починаючи з iOS 14.5, додатки повинні запитати дозвіл користувача через ATTrackingManager перед доступом до IDFA. Без дозволу ASIdentifierManager.shared().advertisingIdentifier повертає нулі (00000000-0000-0000-0000-000000000000). Додаток без правильної реалізації ATT отримує відхилення при перевірці за гайдлайном 5.1.2, а рекламні мережі отримують нульові дані атрибуції.
Що саме потрібно зробити
Info.plist: ключ NSUserTrackingUsageDescription є обов'язковим. Без нього додаток падає з винятком при виклику requestTrackingAuthorization. Текст повинен бути конкретним — Apple відхиляє подачі з загальними формулюваннями на кшталт «для покращення досвіду». Робочий приклад: «Ми використовуємо дані пристрою для показу релевантної реклами та вимірювання ефективності рекламних кампаній».
Момент відображення. requestTrackingAuthorization можна викликати лише один раз — наступні виклики не відображають діалог, а одразу повертають кешовану статус. Тому час важливий: показуйте після онбордингу, не при холодному старті. Користувач, який не розуміє, чому потрібен доступ, натисне «Не запитувати».
import AppTrackingTransparency
import AdSupport
func requestTrackingPermission() async {
// Чекаємо, поки додаток стане активним — інакше діалог не з'явиться
await MainActor.run {
guard UIApplication.shared.applicationState == .active else { return }
}
let status = await ATTrackingManager.requestTrackingAuthorization()
switch status {
case .authorized:
let idfa = ASIdentifierManager.shared().advertisingIdentifier.uuidString
// Передаємо IDFA до SDK рекламної мережі
configureAdSDKs(withIDFA: idfa)
case .denied, .restricted:
// Ініціалізуємо SDK у режимі без трекінгу
configureAdSDKs(withIDFA: nil)
case .notDetermined:
break
@unknown default:
break
}
}
Часта помилка — виклик requestTrackingAuthorization до того, як додаток став .active. Діалог просто не з'являється, статус залишається .notDetermined, і додаток ніколи більше не запитає. Це складно відтворити в симуляторі, але легко виловити на реальному пристрої при першому запуску.
Інтеграція з SDK рекламних мереж
Facebook (Meta) Audience Network, Google AdMob, AppsFlyer, Adjust — всі ці SDK повинні бути ініціалізовані після отримання статусу ATT, інакше вони стартують без IDFA та кешують цей факт.
// AppDelegate або SceneDelegate
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, ...) {
Task {
await requestTrackingPermission()
// Тільки після цього
initializeAnalyticsSDKs()
initializeAdSDKs()
}
}
SKAdNetwork: для атрибуції без IDFA. Список SKAdNetworkItems у Info.plist потрібно оновлювати при кожному додаванні нової рекламної мережі. Meta, Google, Unity та інші мережі публікують свої ідентифікатори SKAdNetwork. Інструмент для генерування актуального списку — SKAdNetwork IDs від MMP-провайдерів.
AppsFlyer вимагає окремої конфігурації режиму роботи без IDFA:
AppsFlyerLib.shared().start()
// При denied/restricted
AppsFlyerLib.shared().anonymizeUser = true
Тестування
Симулятор не відображає діалог ATT. Тестуйте лише на реальному пристрої. Скиньте статус дозволу для конкретного додатка: Параметри → Приватність → Відстеження або повна переустановка додатка.
Для автоматизованого тестування — ATTrackingManager можна замінити через протокол у тестах без звернення до реального API.
Процес роботи
Аудит поточної реалізації ATT та ініціалізації SDK, перевірка Info.plist.
Реалізація правильного потоку: момент відображення, обробка всіх статусів, передача IDFA до SDK.
Інтеграція з конкретними SDK рекламних мереж (Meta, AdMob, AppsFlyer/Adjust).
Тестування на пристрої, перевірка поведінки при статусі denied.
Орієнтири за часом
Реалізація ATT з одним-двома SDK — 1 день. При наявності складної матриці рекламних мереж та необхідності конфігурації SKAdNetwork — до 3 днів.







