0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AdMob UMP(User Messaging Platform)同意フロー実装で踏んだ3つの地雷 - GDPR/ATT/iOS審査と共存する方法

0
Posted at

個人開発のiOSアプリにAdMob広告を組み込む際、UMP(User Messaging Platform)で同意フローを実装したら、ATTやiOS審査要件と絡んで地雷を3つ踏みました。

  • ハマり①: ATTとUMPの 表示順序 を間違えてパーソナライズ広告が出なくなった
  • ハマり②: GDPR地域外で動作確認できず「動いていない」と勘違いしてSDK調査に3時間溶かした
  • ハマり③: 設定画面から 同意の再表示 ができない実装で審査リジェクトの危機

「広告SDK入れて終わり」ではないので、これから組み込む方の参考になれば。


前提知識: そもそもUMPとは何か

UMP(User Messaging Platform)はGoogleが提供する 同意管理プラットフォーム です。EEA/UK/スイス向けのGDPR同意取得をハンドリングしてくれる仕組みで、AdMobを使う場合は実質必須になっています。

iOS開発者が押さえるべきは 「UMP」「ATT」「AdMob」が3層で絡んでいる という点です。

何をするか 関連法規/ポリシー
UMP EEA向けGDPR同意取得 GDPR / Google EU User Consent Policy
ATT IDFA(広告識別子)アクセス許可 Apple App Tracking Transparency
AdMob SDK 広告配信 Google AdMob ポリシー

それぞれ要件が違うので、片方だけ実装しても他方の要件を満たせません。


ハマり① ATTとUMPの表示順序問題

何が起きたか

最初、何も考えず以下の順序で実装しました。

// ❌ ATTを先に出してしまった
func didFinishLaunching() async {
    // ATTダイアログ表示
    let attStatus = await ATTrackingManager.requestTrackingAuthorization()

    // UMP同意フォーム表示
    await requestUMPConsent()

    // 広告SDK初期化
    MobileAds.shared.start()
}

EEA地域でテスト(後述)したら、ATTで「Allow」を押したのにパーソナライズ広告が出ない状態に。原因究明に時間を溶かしました。

なぜダメだったか

GoogleのドキュメントとAppleのガイドラインを照らし合わせると、以下の事情があります。

  • ATTで「Allow Tracking」を選んでも、UMPでGDPR同意していないと、AdMobはパーソナライズ広告を配信できない
  • 逆もしかりで、UMPで同意してもATTで拒否すればIDFAは取得できない
  • 両方のクリアが必要で、順序を間違えるとUXが破綻する

特にユーザー視点で考えると、いきなりATTで「トラッキングを許可しますか?」と聞かれた後にGDPR同意フォームが出ると、**「さっきのATTダイアログは何だったの?」**となってチャーンします。

解決策: UMP → ATT → AdMob初期化の順序

Googleが公式に推奨している順序です。

// ✅ 正しい順序
@MainActor
final class AdConsentCoordinator {
    static let shared = AdConsentCoordinator()

    func bootstrap() async {
        // 1. UMP同意フローを先に実行
        await requestUMPConsent()

        // 2. UMPの結果を踏まえてATTを表示
        //    (EEAでない地域ではUMPはno-opになる)
        if #available(iOS 14, *) {
            _ = await ATTrackingManager.requestTrackingAuthorization()
        }

        // 3. AdMob SDK初期化
        if ConsentInformation.shared.canRequestAds {
            MobileAds.shared.start()
        }
    }

    private func requestUMPConsent() async {
        let parameters = RequestParameters()
        parameters.isTaggedForUnderAgeOfConsent = false

        do {
            try await ConsentInformation.shared
                .requestConsentInfoUpdate(with: parameters)
        } catch {
            print("UMP requestConsentInfoUpdate error: \(error)")
            return
        }

        guard let vc = await topViewController() else { return }

        do {
            try await ConsentForm.loadAndPresentIfRequired(from: vc)
        } catch {
            print("UMP loadAndPresentIfRequired error: \(error)")
        }
    }
}

ポイントは以下の通りです。

  • UMP → ATT → AdMob.start() の順を厳守する
  • ConsentForm.loadAndPresentIfRequiredEEA地域でのみフォーム表示、それ以外では何もせずに完了する
  • canRequestAdsfalse の状態で MobileAds.shared.start() を呼ぶと、非パーソナライズ広告すら表示できない設定になることがある

補足: 非パーソナライズ広告のフォールバック

ユーザーがUMPで「同意しない」を選んだ場合でも、非パーソナライズ広告は配信できますcanRequestAds の判定はその両方を含む形になるので、原則これで分岐すればOKです。

if ConsentInformation.shared.canRequestAds {
    // 広告リクエスト可
    loadBannerAd()
}

ハマり② GDPR地域外でのテストで詰む

何が起きたか

実装が終わって自分のiPhoneで動作確認しても、UMP同意フォームが一切表示されない

「コードが間違っているのか?」「SDKのバージョンか?」と3時間ほどデバッグして、ようやく気づきます。

自分は日本にいるのでGDPR適用地域外。同意フォームは原則表示されない。

これ、知らないと気づくのに本当に時間がかかります。SDKは「正常動作」しているので、エラーログも出ません。

解決策: UMPDebugSettings で地域を偽装

UMPには開発・テスト用のデバッグ機能があります。

private func requestUMPConsent() async {
    let parameters = RequestParameters()
    parameters.isTaggedForUnderAgeOfConsent = false

    #if DEBUG
    let debugSettings = DebugSettings()
    debugSettings.geography = .EEA  // EEA地域として動作させる
    debugSettings.testDeviceIdentifiers = [
        "YOUR-TEST-DEVICE-ID"
    ]
    parameters.debugSettings = debugSettings
    #endif

    // ... 以下同じ
}

テストデバイスIDの取得方法

testDeviceIdentifiers には自分の端末のIDを入れる必要があります。これも取得方法がやや独特で、一度デバッグ実行してログから拾う という手順を踏みます。

  1. requestConsentInfoUpdate を実行
  2. Xcodeのコンソールに <UMP SDK>To enable debug mode for this device, set: UMPDebugSettings.testDeviceIdentifiers = @[ @"XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX" ] のようなログが出る
  3. その UUID を testDeviceIdentifiers に追加して再ビルド

同意状態のリセット

テスト中、何度も同意フォームを表示したい場面があります。一度同意/拒否すると次回以降フォームが出ないので、リセット用APIを使います。

#if DEBUG
func resetConsentForTesting() {
    ConsentInformation.shared.reset()
}
#endif

設定画面の隅に「DEBUG: Reset Consent」ボタンを置いておくと開発が捗ります(リリースビルドでは #if DEBUG で除外)。


ハマり③ 設定画面からの同意再表示が必須

何が起きたか

実装を終えて、「これでいけるだろう」とTestFlightに上げてレビューに回したところ、Apple審査でもAdMobポリシーでも同意の再表示要件が確認される ことを知りました。

具体的には以下の要件があります。

  • ユーザーが 後から同意状態を変更できる導線 を提供する必要がある
  • 設定画面・プライバシー設定画面などにボタンを置くのが一般的
  • ボタン表示条件は GDPR適用地域でのみ表示 が望ましい(地域外で表示すると逆に混乱)

これに気づいたのは審査リジェクトされた後で、修正リリースで対応する羽目になりました。

解決策: 条件付きで再表示ボタンを設置

UMP SDKは「再表示ボタンを出すべきか」の判定APIを持っています。

@MainActor
final class PrivacySettingsViewModel: ObservableObject {
    @Published var shouldShowPrivacyOptionsButton: Bool = false

    func updateState() {
        let status = ConsentInformation.shared.privacyOptionsRequirementStatus
        shouldShowPrivacyOptionsButton = (status == .required)
    }

    func presentPrivacyOptionsForm() async {
        guard let vc = topViewController() else { return }

        do {
            try await ConsentForm.presentPrivacyOptionsForm(from: vc)
            // フォーム閉じた後の状態を反映
            updateState()
        } catch {
            print("presentPrivacyOptionsForm error: \(error)")
        }
    }
}

設定画面のSwiftUI側はこんな感じになります。

struct PrivacySettingsView: View {
    @StateObject private var viewModel = PrivacySettingsViewModel()

    var body: some View {
        Form {
            // ... 他の設定項目

            if viewModel.shouldShowPrivacyOptionsButton {
                Section("広告に関する設定") {
                    Button("広告のパーソナライズ設定を変更") {
                        Task {
                            await viewModel.presentPrivacyOptionsForm()
                        }
                    }
                }
            }
        }
        .onAppear { viewModel.updateState() }
    }
}

privacyOptionsRequirementStatus.required を返すのは EEA地域のユーザーのみ なので、日本のユーザーには自動的に非表示になります。

App Storeレビューガイドラインとの関係

Appleの審査ガイドライン5.1.1にはトラッキング・データ取扱いの透明性に関する規定があり、ユーザーが同意を後から取り消せる手段の提供 が求められます。UMPの再表示ボタンはこの要件にも対応できる位置付けなので、設定画面に置いておくのは保険として強く推奨 です。


まとめ

AdMobのUMP同意フロー実装で押さえるべきポイントは以下の通りです。

  1. 表示順序は UMP → ATT → AdMob.start() を厳守する
  2. GDPR地域外での動作確認は DebugSettings.geography = .EEA で偽装する
  3. 設定画面からの同意再表示は必須要件。privacyOptionsRequirementStatus で出し分け

「広告SDKを入れる」と一言で言っても、GDPR / ATT / Apple審査ガイドラインが3層で絡むため、実装よりむしろ要件整理に時間を使う のが現実です。

公式ドキュメントは整っているのですが、それぞれ別ドキュメントに分散しているため全体像が掴みにくい。本記事が「3つの地雷」を先に踏まずに済むためのチェックリストになれば嬉しいです。

次回はこのアプリで採用したCore Data + CloudKit のスキーマ設計について書く予定です。学習アプリ特有の「マスタデータ更新×ユーザー進捗保護」のジレンマで半日溶かした話を共有します。

何か質問・ツッコミがあれば、コメントでお気軽にどうぞ。


参考リンク

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?