iOS14、UnityAdsのApp Tracking Transparency(ATT)対応の申請で、リジェクトに対応した話

## はじめに
UnityAdsなどの広告を表示する場合、ユーザのトラッキングに使用されるデータとしてIDや使用状況データを送信することになります。
iOS14から、初めてアプリを起動する場合に、広告にIDFA（広告用の識別ID）をアプリが提供することをユーザに示して許可を貰うことが必要となりました。

単純にこのダイアログを出力し、そのように対応するというだけの話ですが、それの申請が通るまでいろいろな問題が発生し、そのたびに頭を痛めしました。
そして無事申請が通りましたので、その過程を紹介します。

## AppTrackingTransparency対応

やりたいことは単純で、このダイアログを出力し、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65274/cd681d65-0051-f889-8777-5f7f139a9f9d.png)
結果によりそのようにすることです。
但し当たり前ですが広告を出す前に出力し、そのように振る舞う必要があります。

#### 開発環境
Unityは2019.4.28f.1です。
PackeageManagerは以下になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65274/dc6b95c0-d419-3c53-1683-6b33e500d38a.png)

UnityAdsで必要なのは
・Advertisementは3.7.3
・iOS 14 Advertising Supportは1.0.0
です。

UnityAdsの広告表示は割愛しますが、iOSのATT対応では以下のコードを追加するだけです。

```
	// リクエスト許可
	if (ATTrackingStatusBinding.GetAuthorizationTrackingStatus() == ATTrackingStatusBinding.AuthorizationTrackingStatus.NOT_DETERMINED) {
		ATTrackingStatusBinding.RequestAuthorizationTracking();
	}
```
これを最初のSceneのStart()に埋めれば終わりなはずでした。

番外編ですが調べると直接Objective-cから呼び出す方法なども検索すると直ぐにたどり着くと思います。

mmファイル

```
#import <AppTrackingTransparency/AppTrackingTransparency.h>
#import <AdSupport/AdSupport.h>

extern "C" void _requestIDFA() {
  [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
  }];
}
```

Unity側C#の実装

```
#if UNITY_IOS
    [DllImport("__Internal")]
    private static extern void _requestIDFA();
#endif

    void Start() {
#if UNITY_IOS
        _requestIDFA();
#endif
    }
```

直接呼び出したい方はこの方法なのでしょう。
但し必要ありません。

#### Buildでハマった

Xcodeでビルドすると以下のメッセージが出力されました
**<font color="Crimson">'unityads/unitymonetization.h' file not found</font>**
検索してみると結果がけっこうあったので、まぁよくあるんだろうなと思い読みあさっていました。
build後のPluginフォルダにUnityAds.Frameworkをダウンロードしそこにコピーするといった内容が主でした。
そしてこう思いました。

**果たしてそんな必要があるのだろうか？**

Buildされたディレクトリをいろいろと確認していると確かにUnityAds.Frameworkディレクトリは存在するもその中にはmetaファイルだけが存在し、mmなどのファイルは存在していませんでした。
結論から言えば、
パッケージをアップロードした際に、前回Assets直下にあったファイルは削除され、新しく
**\Library\PackageCache\com.unity.ads@3.7.3\Plugins\iOS**
ディレクトリにmmなどのファイルが存在していますが、
**<font color="Crimson">前回のパッケージのディレクトリは削除されていなかったため、Build時に古い同名のディレクトリをBuildディレクトリ内に含め、新しい同名のディレクトリはBuildディレクトリ内にコピーされていなかったようです。</font>**
なのでその古いディレクトリを全て削除して問題解決しました。
これは悩みますよね。
たぶんですが、この検索をしている方は同様の内容ではないかと思っています。

#####Xcodeでの操作

私はWindowsで開発を行い、Build時にはMacBookに転送してXcodeでビルドしています。
(BuildするたびにXcodeでも設定が必要だと面倒なうえ、Releaseする場合には細心の注意が必要になりいやですよね）

http://hhr.holy.jp/mimitanikki/?p=339

何度も参考にさせて頂きましたページには<font color="Crimson">FrameWorkを２つ足す</font>ことが書かれていますが、
**私の場合は必要ありませんでした。**

Plistの修正も必要ですが

https://alanyeats.com/post/unityapptrackingtransparencypopup/

このページにある**4 Post build steps**のスクリプトをそのまま利用させて頂きました。

```
   const string TrackingDescription =
        "This identifier will be used to deliver personalized ads to you. ";
```
スクリプトの中のこのconst定義の言葉を差し替えて、以下にしました。

```
const string TrackingDescription =
		"お好みの広告を表示するために使います。";
```

これでXcodeでの操作は最小限に留めることが出来ると思います。

#### 確認でハマった
デフォルトでいいえだった問題。

設定＞プライバシー＞トラッキング
のAppからのトラッキング要求を許可がこの状態だと全ていいえの状態となっており、ATTの対応をしたアプリでもダイアログは出力されません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65274/dff2d3ac-5fc4-d5ba-bdae-b05fe5c7b2cb.png)
*これはいいえの状態です。*

単純にCodeを修正しても出力されない場合って、修正に問題があるか、或いは修正が足りなかったと思っちゃいますよね。
パターンを変え数回ビルドを試しましたが出力されず、再インストールして確認しても出力されず、

http://hhr.holy.jp/mimitanikki/?p=339

1つのアプリで1回しかダイアログは出ないので、何度か確認したい場合は実機からアプリを削除し再インストールする、と書いてある記事もありますが、アプリの削除＆再インストールでは必ず再度ダイアログを出すことはできませんでした。

と書かれているため、もしや知らぬ間に設定してしまい、既に確認できない状態では！？
と不安になりました。
それでも確認できてないのに提出は出来ないのでいろいろ調べていたらそもそもデフォルトでOFFであったため、ダイアログが出力されなかったことが判明しました。
無事ダイアログの出力が確認でき、もちろんアンインストールした場合は再度ダイアログの出力も確認できました。
上の記事とは結果が違いますが、Versionやら設定やらいろいろ違いがあるのでしょう。
ただ、私の環境では
**<font color="Crimson">
アンインストールした場合に再度インストールすれば、ダイアログの出力は確認できた。
</font>**
ことを伝えておきます。
これで完了と思い申請しました。

#### 提出してリジェクトでハマった

提出したらリジェクトされてしまいました。
リジェクトの文言と同時に以下のスクショが送られてきました。

![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65274/52738b93-737f-b490-ea74-c073f4630ba4.png)

文言を要約すると
>このページが出力されるのでATTに対応出来ていません。

とのことでした。


ATT問題で記事を検索するとみなさんここで無事解決していますが、私は解決されませんでした。
ここで頭をよぎったのはBuildでハマった時と同じ、SDKのバージョンアップで何か見えない問題が発生しているのでは？
ということでした。
よくあるのは、0から素直にインストールすれば起きない問題も、バージョンアップの場合、不必要なリンクが参照されたり、設定が更新されなかったりで素直に動かないことはあるあるなので、もう一度UnityAdsのVersionUpを確認しようと思いました。（結局は関係なかったけれど）
ただ、結果的にいうと、UnityAdsのWeb画面でSDKのバージョンが古いという警告が出たままだったので、ボタンをポチポチ押していたら解消され、ATTと非ATTの結果の違いの画面が出力されているので、対応済みとなったかと考えました。
端末側は修正しませんでしたが、buildversionが上がらないと審査されないという話はよく聞くのでversionupだけ行ったbuildを作成し、以下の文言を加え再度申請しました。

>私はそのダイアログを確認していません。
>但し、私はそのダイアログが出力される原因はサーバ側のversionによるものと考えます。
>サーバ側のversionupを完了させたので再度確認をお願いします。

そして１日寝かせると同じ文言でリジェクトされ、また絶望しました。

絶望しましたが、Reviewerに対して以下の質問をしました。

>あなたは、次のステージボタンを押下しただけでその画面が出力されましたか？

回答はこうでした。
> Also we just tap on “次のステージ” and will appear the attached screenshot.

次のステージボタンをタップしただけでこのスクリーンショットが出力されます。

## GDPR対応

たぶん当時2021.6.28時点において、UnityAdsで発生するATT対応のリジェクトの問題がGDPRに起因することを示唆している記事はこれぐらいだったのではないでしょうか。

https://forum.unity.com/threads/app-rejected-because-unity-ads-own-data-collection-permission-request-violates-att-guidelines.1103065/

この記事では正に私と同じ問題でリジェクトされているスクショに対し、

>UnityAdsではATTポップアップを表示しない。
表示するのはGDPRのポップアップだけだ。
但し、ATTでIDFAの確認をした後にGDPRで同じ内容を確認することは好ましくない。

って感じのことが書かれていました。

そして以下の仮説を立てました。
「ReviewerはEU圏内のため、GDPRのダイアログが出力されが、私は日本なので出力されない。」

そして以下のドキュメントを紹介していました。

https://unityads.unity3d.com/help/legal/data-privacy-and-consent

このドキュメントでは
Advertisement.SetMetaData(MetaData)
関数で、gdprのメタデータを設定すればリジェクトされたスクショを表示しないことが書かれていました。
次はこの修正を行い提出しようと考えました。
実装は以下です。

```
IEnumerator ShowBannerWhenInitialized() {
	// 初期化
	Advertisement.Initialize(_gameId, _testMode);

	// GDPRダイアログ対応
	if (ATTrackingStatusBinding.GetAuthorizationTrackingStatus() == ATTrackingStatusBinding.AuthorizationTrackingStatus.AUTHORIZED) {
		MetaData gdprMetaData = new MetaData("gdpr");
		gdprMetaData.Set("consent", "true");
		Advertisement.SetMetaData(gdprMetaData);
	}
	else {
		MetaData gdprMetaData = new MetaData("gdpr");
		gdprMetaData.Set("consent", "false");
		Advertisement.SetMetaData(gdprMetaData);
	}

	while (!Advertisement.isInitialized) {
		yield return new WaitForSeconds(0.5f);
	}
	Advertisement.Banner.SetPosition(BannerPosition.BOTTOM_CENTER);
	_showBanner = false;
	yield break;
}
StartCoroutine(ShowBannerWhenInitialized());
```
一番困ったのはこのメタデータをAdvertisementの初期化前に設定すべきか、初期化後に設定すべきかです。
迷いますよね。
私は初期化後に設定しました。
結論から言えばこれで審査を通ったので、このversionでは正解だと思います。


#### 試すも確認出来なくて困った
当たり前ですが日本なのでこのGDPRのダイアログは表示されないので、消せたかどうかも確認できません。
一旦端末をイギリスなどに変更し確認しようかと思いましたが、住所なども入れる必要があったため怖くて止めました。

そしてこうコメントし提出しました
>GDPRのダイアログであると推測していますが、日本から確認しているのでGDPRのダイアログは出力されず、問題を確認出来ませんでした。
>但し以下の情報がありましたので書かれている通りに修正しました。
>https://unityads.unity3d.com/help/legal/data-privacy-and-consent
>これで問題が解決されることを祈ります。

そして無事リリースされました

https://apps.apple.com/us/app/%E3%83%9E%E3%82%A4%E3%83%B3%E3%82%B9%E3%82%A4%E3%83%BC%E3%83%91%E3%83%BC-%E3%83%90%E3%83%88%E3%83%AB/id1573104410

## 終わりに
書きかけですが、時事ネタなので投稿します。
同じ問題を抱える方に少しでも力になればと思います。