[Unity] iOS で ATTダイアログ表示前に admob で設定したUMP IDFA メッセージを表示したい！

# 前置き

iOS 14以降にて表示することが可能になっていた ATT(App Tracking Transparency)ダイアログだが、筆者はAdmob のために利用していた。

で、最近のGoogle Admob のアップデートで、ATTダイアログ表示前に、カスタムIDFAメッセージを表示できるようになった。（どうやら Google User Messaging Platform SDK というのを使うらしい。）


![Screenshot 2023-11-26 at 18.28.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1900756/4587b545-6ac0-5074-e244-7390f9bc358a.png)

このメッセージは、Admob ダッシュボード上で設定でき、アプリ側ではAPIのコールをしさえすれば表示できるらしい。

![Screenshot 2023-11-26 at 18.25.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1900756/6db2b452-4b3b-91a6-3c11-cabdb087f769.png)

てことで、Unity 上で　iOS native plugin を設置することで対応したい！

# やること

- ATT ダイアログを表示させる旧スクリプト → プレIDFA メッセージを表示させる新スクリプトに移行
- 今まで　objective-c (.mm ファイル)でiOS native plugin を作成していたが、swift コードの方が好きなのでswift で書くことにする。

# 必要なもの

Mobile Ads SDK (for Unity) のみ。

::: note warn
ただし、Mobile Ads SDK のバージョンは、 UMP SDK (Google User Messaging Platform SDK) が含まれているものを使用してください。
:::

# やったこと



公式URLを参照しつつ、

https://developers.google.com/admob/ios/privacy#swift_3

1. 旧スクリプトの削除 (ATTダイアログ表示用の`objective-c`ファイル)
1. 新スクリプトの作成 (IDFAダイアログ表示用の`swift`ファイル)
1. 新スクリプト`swift`をUnityから呼び出すための`C#`スクリプト

## 1. 旧スクリプトの削除 (ATTダイアログ表示用の`objective-c`ファイル)

旧ファイルを削除
`Assets/Plugins/iOS/RequestAttDialog.mm`

```objective_c: RequestAttDialog.mm
 #import <Foundation/Foundation.h>
 #import <AppTrackingTransparency/AppTrackingTransparency.h>
 #import <AdSupport/AdSupport.h>
 
 //この範囲のコードはCで書かれてるよってこと
 #ifdef __cplusplus
 extern "C" {
 #endif
 //ATTダイアログを表示するメソッド
 void requestIDFA() {
     if (@available(iOS 14, *)){
         [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
         // Tracking authorization completed. Start loading ads here.
         // [self loadAd];
         }];
     }
 }
 #ifdef __cplusplus
 }
 #endif

```

## 2. 新スクリプトの作成 (IDFAダイアログ表示用の`swift`ファイル)
新スクリプトの作成
`Assets/Plugins/iOS/RequestIDFADialog.swift`

```swift: RequestIDFADialog.swift
import Foundation
import AppTrackingTransparency
import UserMessagingPlatform

extension UIViewController {
    static func getFrontViewController() -> UIViewController? {
        let keyWindow = UIApplication.shared.connectedScenes
            .filter({$0.activationState == .foregroundActive})
            .map({$0 as? UIWindowScene})
            .compactMap({$0})
            .first?.windows
            .filter({$0.isKeyWindow}).first

        let vc = keyWindow?.rootViewController
        guard let _vc = vc?.presentedViewController else {
            return vc
        }
        return _vc
    }
}

public class UmpPlugins {
    public static func requestIDFA() {
        if #available(iOS 14, *) {
            // UMPRequestParameters
            let parameters = UMPRequestParameters()
            // 許諾年齢未満であるか？
            parameters.tagForUnderAgeOfConsent = false
            
            // 事前許諾プロンプトの提示状況をリクエスト
            // メインスレッドで呼ぶ必要あり
            UMPConsentInformation.sharedInstance.requestConsentInfoUpdate(
                with: parameters,
                completionHandler: { error in
                    if let error = error {
                        // エラー
                        debugPrint(error.localizedDescription)
                    } else {
                        // 事前許諾プロンプトが利用可能かチェック
                        let formStatus = UMPConsentInformation.sharedInstance.formStatus
                        // UMPFormStatus.unknown：0 不明
                        // UMPFormStatus.available：1 利用可能
                        // UMPFormStatus.unavailable：2 利用不可
                        if formStatus == .available {
                            DispatchQueue.main.async {
                                // プロンプトをロード
                                UmpPlugins.loadIDFA()
                            }
                        }
                    }
                }
            )
        }
    }
    
    private static func loadIDFA() {
        
        // プロンプトの提示が必要
        guard let vc = UIViewController.getFrontViewController() else {
            return
        }
        UMPConsentForm.loadAndPresentIfRequired(from: vc)
    }
}

@_cdecl("requestIDFA")
public func requestIDFA()
{
    return UmpPlugins.requestIDFA()
}
```


## 3. 新スクリプト`swift`をUnityから呼び出すための`C#`スクリプト

以下をどこかに設置。

```c#:ShowAttDialog.cs
using System.Runtime.InteropServices;
public class ShowAttDialog
{
#if UNITY_IOS
    [DllImport("__Internal")]
    private static extern int requestIDFA();

    //　public staticにしているので外部ファイルで「ShowAttDialog.RequestIDFA()」とすれば呼び出せる。
    public static void RequestIDFA()
    {
        requestIDFA();
    }
#endif
}
```

## 4. Admob ダッシュボードにてアプリを追加

IDFA 設定画面に行き、アプリ一覧に、作成中の新規アプリを追加する、

# おしまい。

参考

https://zenn.dev/bon/articles/f9defae4f8a3b1

https://zenn.dev/kamimi01/articles/handle_att_in_my_personal_projects#app-tracking-transparency-について

https://zenn.dev/kamimi01/articles/implement_idfa_message_with_admob