そういうのがいいブログ

アプリ個人開発 まるブログ

アプリ開発覚え書き

【Unity】iOS14.5以降でIDFA取得するためにATT対応する方法 

追記<2023年9月>

本記事内容で対応できなくなっていました。
以下の記事を参照してください。

marumaro7.hatenablog.com

はじめに

タイトル専門用語でわけわからん!
はい、私も同じです。
とりあえず、広告収益に影響が出る恐れがあるということなので、
対応していきますっ!

IDFAとは?

IDFAはIdentifier For Advertisingの略

端末固有のIDで、これを使ってデータが収集されます。
そして、そのIDのユーザーに興味がありそうな広告を
表示するために使用されます。

なので、IDFAを取得していないと、 ガチゲーマーに美容液の広告が表示されたりするので、
広告をタップしてもらう確率が低くなると予想されています。

(ガチゲーマーは美容液使わないという話では無いですよっ!
広告をタップする確率が高いか低いかの話ですっ!)

iOS14.5から仕様変更

iOS14.4まではこのIDFAがユーザーの許可無しで取得できていました。

しかし、iOS14.5からIDFAを取得するにはユーザーの許可が必要になりました。

ATTとは?

ATTはAppTrackingTransparency の略

iOS14からIDFAの許諾をATTシステムで管理するようになりました。

「勝手にIDFA取得させねぇから!システム」と思っておけば良いと思います。
(よくわかってない)

許可リクエスト実装

IDFAを取得するために、
ユーザーへ許可を問うリクエストウインドウを表示する必要があります。
今回はその許可リクエストを実装します。

1.前提条件

Google Mobile Ads Unity Plugin v5.4.0
・広告は実装済

2.コード実装

コード実装の流れは下記です。
1.Objective-Cの言語でリクエストウインドウを表示する処理を書く
2.C#にて↑で作った処理を呼び出す

2-1.Objective-Cの処理

2-1-1.拡張子mmのファイルを作成する

テキストエディットで適当にテキストファイルをデスクトップに作ります。

ファイルの名前を「RequestIDFA.mm」に変更します。
ファイル名は何でも良いですが、拡張子を「.mm」にして下さい。

2-1-2.リクエストウインドウを表示する処理を書く

「RequestIDFA.mm」に処理を書いていきます。

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

extern "C" void _requestIDFA() {
    if (@available(iOS 14.5,*)) {
        [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
            // Tracking authorization completed. Start loading ads here.
            // [self loadAd];
          }];
    }
}

2-1-3.Unityにファイルを追加

Unityにファイルを追加します。
Assets>Plugins>iOSに今回作成した「RequestIDFA.mm」を追加して下さい。

2-2.Unity(C#)での処理

2-2-1.スクリプト作成

C#スクリプトを作成します。
今回は「IDFA」という名前で作りました。
スタート関数でリクエストウインドウを呼び出す内容となっています。

<コード変更 2021年10月1日>
iOS15では起動直後にリクエストウインドウを表示しようとしても表示されません。
そのため、1秒遅延させて表示する内容に変更しました。
(Invoke関数を使って1秒遅延させただけです。)

<追記 2022年1月17日>
カメラ権限など他の権限ウインドウも同時に開くようですと、
リクエストウインドウが表示されない場合があります。
その場合は、任意のタイミングで呼び出すと良いでしょう。

<追記 2022年5月24日>
Unityエディター上で動作させるとエラーが出るので(エラーが出るだけで動作上問題無し)
Unityエディターの場合は動作させないように分岐を追加

using UnityEngine;
using System.Runtime.InteropServices;

public class IDFA : MonoBehaviour
{

#if UNITY_EDITOR//Unityエディターの場合の処理

    //何もしない

#elif UNITY_IOS//Unityエディターでない かつ iOSの場合に処理

    //RequestIDFA.mm で定義しているObjective-C(iOSで使用されている言語)の関数を以下のようにC#側で定義する
    [DllImport("__Internal")]//iOSのプラグイン読み込み 参考 https://docs.unity3d.com/ja/2018.4/Manual/NativePlugins.html
    private static extern void _requestIDFA();//外部で実装されるメソッドを宣言 参考 https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/extern

#endif//Unityエディターでない かつ iOSの場合の処理範囲終わり


    private void Start()
    {
        Invoke("DelayIDFA", 1);//1秒遅らせてDelayIDFA()の呼び出し (iOS15では遅延させないと表示されないため)
    }


    private void DelayIDFA()
    {
#if UNITY_EDITOR//Unityエディターの場合の処理

        //何もしない

#elif UNITY_IOS//Unityエディターでない かつ iOSの場合に処理

        _requestIDFA();//IDFAリクエストの実行

#endif//Unityエディターでない かつ iOSの場合の処理範囲終わり

    }

}



ほんの少しコードを短くする場合は下記

using UnityEngine;
using System.Runtime.InteropServices;

public class IDFA : MonoBehaviour
{
#if !UNITY_EDITOR && UNITY_IOS
    //RequestIDFA.mm で定義しているObjective-C(iOSで使用されている言語)の関数を以下のようにC#側で定義する
    [DllImport("__Internal")]//iOSのプラグイン読み込み 参考 https://docs.unity3d.com/ja/2018.4/Manual/NativePlugins.html
    private static extern void _requestIDFA();//外部で実装されるメソッドを宣言 参考 https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/keywords/extern
#endif

    private void Start()
    {
        Invoke("DelayIDFA", 1);//1秒遅らせてDelayIDFA()の呼び出し (iOS15では遅延させないと表示されないため)
    }

    private void DelayIDFA()
    {
#if !UNITY_EDITOR && UNITY_IOS
        _requestIDFA();//IDFAリクエストの実行
#endif
    }
}

2-2-2.空のオブジェクトに割付け

作成した「IDFA」のコードを空のオブジェクトに割り付けます。
空のオブジェクトの名前も「IDFA」にしました。

2-2-3.ビルド

ビルドしてUnity-iPhone.xcodeprojを開いて下さい。

一応ビルド手順
marumaro7.hatenablog.com

3.Xcodeでの設定

Xcodeでは
1.Info.plistに「Privacy - Tracking Usage Description」を追加
2.「AppTrackingTransparency.framework」を追加
を行う必要があります。

3-1.Info.plistに「Privacy - Tracking Usage Description」を追加

Unity-iPhone
>info.plist (Xcodeバージョン13.0では表記がinfoになっています。)
>「+」ボタン(マウス カーソルをInformation Property Listに合わせると出現します)
>「Privacy - Tracking Usage Description」と入力し追加
>追加した「Privacy - Tracking Usage Description」のValueに説明書きを追加
例:あなたの好みに合わせた広告を表示するために使用されます
Valueに入力しないと例外処理とされてしまうようなので必ず入力しましょう

文章の多言語化はこちらの「アプリ名ローカライズ iOS編」の要領で
NSUserTrackingUsageDescription = "日本語";
とすればできます。 marumaro7.hatenablog.com

NSUserTrackingUsageDescriptionの入力例
(画像には文末のセミコロンの入力できてませんのでお忘れなく!)

3-2.「AppTrackingTransparency.framework」を追加

>Unity-iPhone
>UnityFramework
>「+」ボタン
>AppTrackingTransparency.frameworkを追加

4.動作確認

iOS14.5以降にだけ表示されます。

もし表示されない場合
端末の
>設定
>プライバシー
>トラッキング
>Appからのトラッキング要求を許可
>オン
になっていることを確認してください。

<2022年2月 追記>
テスト広告を表示するには、
ATTウインドウの「許可」を押さないと表示されませんのでご注意ください。

自動で設定

「3.Xcode」での設定は
Unity側の設定で自動化することができます。

以下を参考にすると良いです。

dolphinetech.com

以下引用

ここでは、プロジェクトビルド後に自動でframeworkを追加し、
info.plistを編集してくれる方法(というかスクリプト)を書いていきます

Assets > Editor にファイルを一つ作ってください(Editorフォルダがない場合は作成してください)

私は、「AddElementsInfoplist」としました

作成したファイルに以下かのような処理(クラス名以外)を実装してください

#if UNITY_IOS
using UnityEditor;
using UnityEditor.Callbacks;
using UnityEditor.iOS.Xcode;
using UnityEngine;
public class AddElementsInfoplist
{
    [PostProcessBuild]
    public static void OnPostProcessBuild(BuildTarget buildTarget, string buildPath)
    {
        // Info.plist に Privacy - Tacking Usage Description(NSUserTrackingUsageDescription)を追加する(ステップ2)
        string infoPlistPath = buildPath + "/Info.plist";
        PlistDocument infoPlist = new PlistDocument();
        infoPlist.ReadFromFile(infoPlistPath);
        PlistElementDict root = infoPlist.root;
        root.SetString("NSUserTrackingUsageDescription", "あなた様の好みに合わせた広告を表示するために使用されます!!!!");
        infoPlist.WriteToFile(infoPlistPath);
        
     // PBXProjectクラスというのを用いてAppTrackingTransparency.frameworkを追加していきます(ステップ3)
        string pbxProjectPath = PBXProject.GetPBXProjectPath(buildPath);
        PBXProject pbxProject = new PBXProject();
        pbxProject.ReadFromFile(pbxProjectPath);
        string targetGuid = pbxProject.GetUnityFrameworkTargetGuid();
        pbxProject.AddFrameworkToProject(targetGuid, "AppTrackingTransparency.framework", true);
        pbxProject.WriteToFile(pbxProjectPath);
    }
}
#endif

これでUnityでビルド後、自動的にframeworkの追加とInfo.plistの編集が行われているはずです!

おわりに

言語化がわからなかったので、
Twitterで助けを求めたらすぐ助けていただきました。
JOEさんありがとうございます。


<追記> iPhoneをiOS14.5にしたら下記の対応が必要です。 marumaro7.hatenablog.com



最後に宣伝させてください。
アプリ開発を始めて丸2年が経ち、
節目としてなにか形にしたいと思い、Udemy講座を出しました!
www.udemy.com

ブログ限定割引リンクは私のプロフィールページにあります。
アプリ開発収益化を時短したい方向けの講座となっております。

Unity本を出版しました!

突然ですが、Unity本を出版しました!
こちらを読むことで、スクリプトの基礎固めができます!
現在、kindle unlimitedで読み放題設定中です。今のうちにどうぞ!


もっと早く教えてほしかった!Unity C#入門

参考

qiita.com dolphinetech.com hirokuma.blog blog.be-style.jpn.com qiita.com qiita.com developers.google.com

<追記 2021年10月1日>

stackoverflow.com qiita.com