ATT ダイアログをいつ出すか問題 — 起動直後の 1 秒遅延
| 開発記録 | QRリーダー
タグ: #iOS #ATT #App Store
ATT(App Tracking Transparency)ダイアログを「いつ表示するか」は、App Store のリジェクト要因にもなる繊細なテーマです。起動直後に出すと拒否率が上がる、出さないとリジェクト。1 秒遅延で落ち着いた話。
ATT ダイアログとは
iOS 14.5 以降、広告のためにユーザーの IDFA を使うには ATT ダイアログでの許可が必要です。表示しないと、広告 SDK が IDFA を取得できず、収益に影響します。
いつ出すかが意外と難しい
Appleのガイドラインでは「アプリを使い始める前後の自然なタイミング」で表示するよう求められています。が、実際の運用ではタイミング設計でハマるポイントが多々あります。
- 起動直後すぎる: スプラッシュ画面の上に出てしまい、ダイアログが乗らない
- 遅すぎる: ユーザーがすでにアプリを操作しており、ダイアログが唐突
- 同意フローの最中: GDPR の UMP ダイアログと被ると地獄
試行錯誤の履歴
コミット履歴を見ると、ATT 表示は何度も調整しています。
- アプリ起動直後に表示 → 表示されないケース報告
- 1 秒の遅延を追加 → 安定して表示されるように
- 文言を全 14 言語に整備
Future.delayed(const Duration(seconds: 1), () {
AppTrackingTransparency.requestTrackingAuthorization();
});
addPostFrameCallback の併用
Swift 側で直接 ATTrackingManager を呼ぶ場合も、起動直後の即時呼び出しは避け、UI が落ち着くまでわずかに遅らせるのが安定する印象です。
import AppTrackingTransparency
func requestAttIfNeeded() {
guard #available(iOS 14.5, *) else { return }
let delay: DispatchTime = .now() + 1.0
DispatchQueue.main.asyncAfter(deadline: delay) {
ATTrackingManager.requestTrackingAuthorization { status in
switch status {
case .authorized:
Analytics.log("att_authorized")
case .denied, .restricted, .notDetermined:
Analytics.log("att_declined_\(status.rawValue)")
@unknown default:
break
}
}
}
}
万華鏡アプリの方では、WidgetsBinding.instance.addPostFrameCallback 内でリクエストするようにしました。Widget ツリーが構築されたあとに呼ぶことで、ダイアログが確実にトップ画面の上に乗ります。
文言の重要性
ATT ダイアログ本体(OS が出す部分)の上に表示できる説明文は、アプリ側で記述します。「広告のために許可してください」とだけ書くと拒否率が高くなるので、「無料で提供を続けるために、関連性の高い広告を表示する目的で利用します」のような言い方に変えたら、許可率が改善しました。
サブタイトルから「価格表記」を外す
App Store 審査周りで関連する話として、「価格表記」をサブタイトルから外した修正もありました。Apple は「無料」「Free」のような表現をストア画面に置くのを嫌がります。これも審査リジェクト経験からの学びです。
まとめ
- ATT は 1 秒遅延 + addPostFrameCallback の組み合わせが安定
- 文言は丁寧に、機械翻訳のままにしない
- 関連で UMP(GDPR 同意)の順序設計も忘れずに
小さなダイアログひとつに、ここまで考えることがあるのが App Store の現実です。