FC2ブログ
    05 «1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.24.25.26.27.28.29.30.» 07

    ハルシオンシステムの気ままBlog

    株式会社ハルシオンシステムのメンバーが送る、UnityやらJavaやらの技術的話題から、自社開発のアプリの宣伝とかとかのブログです。ほんと気ままにいきたいと思います。更新日は毎週 月 木でっす!

     

    【ハルシオンブログ】UnityのプロジェクトでATTダイアログを出してみた。え?これでいいの? 

    こんにちは。坂内っす。
    今週は東京ゲームショー2022がありますね。
    色々と気になるブースもありますね!

    今年は特に行く予定もなく、家で大人しくポケガ3開発してます。

    さて、先週はiOSへのビルドで時間食われてました。
    その中で、ATTダイアログを出すところでいい感じにはまったので、まとめておきます。
    色々なサイトのを試したのですが、結局以下に落ち着きました。


    【ATTダイアログ】
    iOS14以降からアプリの新規、アップデート時にATT(App Tracking Transparency)の対応が必須になりました。
    https://developer.apple.com/jp/news/?id=8rm6injj

    こんなの。
    これ入れないとリジェクトされるぽいですよ。

    では行ってみましょう。


    ①Assets/Plugins/iOSの下にATTダイアログを出すネイティブコードを作成する

    今回は「RequestAttDialog.mm」という名前のコードを作成しました。

    [RequestAttDialog.mm]

    #import
    #import
    #import
    #ifdef __cplusplus
    extern "C" {
    #endif
    void requestIDFA() {
    if (@available(iOS 14, *)){
    [ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:^(ATTrackingManagerAuthorizationStatus status) {
    // Tracking authorization completed. Start loading ads here.
    // [self loadAd];
    }];
    }
    }
    #ifdef __cplusplus
    }
    #endif



    ②ATTダイアログのネイティブコードを呼び出すクラスを作成する
    これはUnityのプロジェクト内ならどこでもおk。

    [ATTDialog.cs]

    #if UNITY_IOS
    using System.Runtime.InteropServices;
    public class ATTDialog
    {
    [DllImport("__Internal")]
    private static extern int requestIDFA();
    public static void RequestIDFA()
    {
    requestIDFA();
    }
    }
    #endif



    ③上記で作成したRequestIDFAをアプリ開始のシーンで呼ぶ。
    タイトルやスプラッシュのシーンとかあれば、そこのStartなんかで呼んであげればいいです。


    void Start(){
    #if !UNITY_EDITOR && UNITY_IOS
    ATTDialog.RequestIDFA();
    #endif
    }


    ④EditorにFrameworkやInfo.plistで設定する必要のあるものをコードで作っておく
    Assets/Editorに「PostXcodeBuild.cs」を作成する。


    //PostXcodeBuild.cs

    using System.IO;
    using UnityEditor;
    using UnityEditor.Callbacks;
    using System.Collections;
    using System.Collections.Generic;
    #if UNITY_IOS
    using UnityEditor.iOS.Xcode;
    #endif

    public class PostXcodeBuild
    {
    #if UNITY_IOS
    private struct InfoplistInfo
    {
    public string key;
    public string value;
    public InfoplistInfo(string str1, string str2)
    {
    key = str1;
    value = str2;
    }
    };

    private struct LocalizationInfo
    {
    public string lang;
    public bool isdefault;
    public InfoplistInfo[] infoplist;
    public LocalizationInfo(string langstr, bool flg, InfoplistInfo[] info)
    {
    lang = langstr;
    infoplist = info;
    isdefault = flg;
    }
    };
    private struct CommonInfoPlistInfo
    {
    public InfoplistInfo[] infoplist;
    public CommonInfoPlistInfo(InfoplistInfo[] info)
    {
    infoplist = info;
    }
    };

    private static LocalizationInfo[] localizationInfo = {
    new LocalizationInfo("en", false, new InfoplistInfo[]
    {new InfoplistInfo("CFBundleDisplayName", "英語のタイトル"),
    new InfoplistInfo("NSUserTrackingUsageDescription", "Please set to Allow to avoid displaying inappropriate advertisements"),
    }),
    new LocalizationInfo("ja", true, new InfoplistInfo[]
    {new InfoplistInfo("CFBundleDisplayName", "日本語のタイトル"),
    new InfoplistInfo("NSUserTrackingUsageDescription", "不適切な広告の表示を避けるために”トラッキングを許可”に設定してください"),
    })
    };


    private static string[] skadnetworkitems = new string[] { "cstr6suwn9.skadnetwork" };


    static void createInfoPlistString(string pjdirpath, LocalizationInfo localizationinfo)
    {
    string dirpath = Path.Combine(pjdirpath, "Unity-iPhone Tests");

    if (!Directory.Exists(Path.Combine(dirpath, string.Format("{0}.lproj", localizationinfo.lang))))
    {
    Directory.CreateDirectory(Path.Combine(dirpath, string.Format("{0}.lproj", localizationinfo.lang)));
    }
    string plistpath = Path.Combine(dirpath, string.Format("{0}.lproj/InfoPlist.strings", localizationinfo.lang));
    StreamWriter w = new StreamWriter(plistpath, false);
    foreach (InfoplistInfo info in localizationinfo.infoplist)
    {
    string convertedval = System.Text.Encoding.UTF8.GetString(
    System.Text.Encoding.Convert(
    System.Text.Encoding.Unicode,
    System.Text.Encoding.UTF8,
    System.Text.Encoding.Unicode.GetBytes(info.value)
    )
    );
    w.WriteLine(string.Format(info.key + " = \"{0}\";", convertedval));
    }
    w.Close();
    }

    static void addknownRegions(string pjdirpath, LocalizationInfo[] info)
    {
    string strtmp = "";
    string pjpath = PBXProject.GetPBXProjectPath(pjdirpath);

    foreach (LocalizationInfo infotmp in info)
    {
    strtmp += "\t\t" + infotmp.lang + ",\n";
    }
    strtmp += "\t\t);\n";

    StreamReader r = new StreamReader(pjpath);
    string prjstr = "";
    string linetmp = "";
    while (r.Peek() >= 0)
    {
    linetmp = r.ReadLine();
    if (linetmp.IndexOf("knownRegions") != -1)
    {
    prjstr += linetmp + "\n";
    prjstr += strtmp;
    while (true)
    {
    linetmp = r.ReadLine();
    if (linetmp.IndexOf(");") != -1)
    {
    break;
    }
    }
    }
    else
    {
    prjstr += linetmp + "\n";
    }
    }
    r.Close();
    StreamWriter sw = new StreamWriter(pjpath, false);
    sw.Write(prjstr);
    sw.Close();
    }

    static void addLocalizationInfoPlist(string pjdirpath, LocalizationInfo[] info)
    {
    string plistPath = Path.Combine(pjdirpath, "Info.plist");
    PlistDocument plist = new PlistDocument();

    plist.ReadFromFile(plistPath);
    var array = plist.root.CreateArray("CFBundleLocalizations");
    foreach (LocalizationInfo infotmp in info)
    {
    array.AddString(infotmp.lang);
    }
    var rootDict = plist.root;
    foreach (LocalizationInfo infotmp in info)
    {
    if (infotmp.isdefault)
    {
    foreach (InfoplistInfo pinfo in infotmp.infoplist)
    {
    string convertedval = System.Text.Encoding.UTF8.GetString(
    System.Text.Encoding.Convert(
    System.Text.Encoding.Unicode,
    System.Text.Encoding.UTF8,
    System.Text.Encoding.Unicode.GetBytes(pinfo.value)
    ));
    rootDict.SetString(pinfo.key, convertedval);
    }
    }
    }
    plist.WriteToFile(plistPath);
    }

    static void addSkAdNetworkItems(string pjdirpath, string[] skadvallist)
    {
    string plistPath = Path.Combine(pjdirpath, "Info.plist");
    PlistDocument plist = new PlistDocument();
    plist.ReadFromFile(plistPath);

    if (skadvallist != null)
    {
    var array = plist.root.CreateArray("SKAdNetworkItems");
    foreach (string value in skadvallist)
    {
    PlistElementDict dict = array.AddDict();
    dict.SetString("SKAdNetworkIdentifier", value);
    }
    }
    plist.WriteToFile(plistPath);
    }

    static void addAppTrackingTransparency(string pathToBuiltProject)
    {
    string pbxProjectPath = PBXProject.GetPBXProjectPath(pathToBuiltProject);
    PBXProject pbxProject = new PBXProject();
    pbxProject.ReadFromFile(pbxProjectPath);
    string targetGuid = pbxProject.GetUnityFrameworkTargetGuid();
    pbxProject.AddFrameworkToProject(targetGuid, "AppTrackingTransparency.framework", true);
    pbxProject.WriteToFile(pbxProjectPath);
    }

    [PostProcessBuild]
    public static void SetXcodePlist(BuildTarget buildTarget, string pathToBuiltProject)
    {
    if (buildTarget != BuildTarget.iOS)
    {
    return;
    }

    foreach (LocalizationInfo entry in localizationInfo)
    {
    /* add infoplist.string */
    createInfoPlistString(pathToBuiltProject, entry);
    }

    /* add knownregions to project */
    addknownRegions(pathToBuiltProject, localizationInfo);

    /* add localization to infoplist */
    addLocalizationInfoPlist(pathToBuiltProject, localizationInfo);

    /* add addSkAdNetworkItems */
    addSkAdNetworkItems(pathToBuiltProject, skadnetworkitems);

    /* add AppTrackingTransparency */
    addAppTrackingTransparency(pathToBuiltProject);
    }
    #endif
    }


    これを作っておけば、XcodeでFrameworkの追加等の手間が省けます。

    ⑤Unityでビルド

    ⑥出来上がったUnity-iPhone.xcworkspaceからXcodeを起動して、ビルド


    最終的にはこちらでATTダイアログが出るようになりました。
    たた、ATTダイアログの戻りを使ったりしてないので、これが正しいのか分からないのが現状…


    こうした方がいいよとかそういうのがあったら是非教えてください!


    ということで、本日はATTダイアログを出してみた。

    では、あでゅ~ノシ

    Category: 開発日記(Unity)

    tb 0 : cm 0   

    コメント

    コメントの投稿

    Secret

    トラックバック

    トラックバックURL
    →http://halcyonsystemblog.jp/tb.php/918-15ab7524
    この記事にトラックバックする(FC2ブログユーザー)