【ハルシオンブログ】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]
②ATTダイアログのネイティブコードを呼び出すクラスを作成する
これはUnityのプロジェクト内ならどこでもおk。
[ATTDialog.cs]
③上記で作成したRequestIDFAをアプリ開始のシーンで呼ぶ。
タイトルやスプラッシュのシーンとかあれば、そこのStartなんかで呼んであげればいいです。
④EditorにFrameworkやInfo.plistで設定する必要のあるものをコードで作っておく
Assets/Editorに「PostXcodeBuild.cs」を作成する。
これを作っておけば、XcodeでFrameworkの追加等の手間が省けます。
⑤Unityでビルド
⑥出来上がったUnity-iPhone.xcworkspaceからXcodeを起動して、ビルド
最終的にはこちらでATTダイアログが出るようになりました。
たた、ATTダイアログの戻りを使ったりしてないので、これが正しいのか分からないのが現状…
こうした方がいいよとかそういうのがあったら是非教えてください!
ということで、本日は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)
« 【ハルシオンブログ】Hierarchy内で特定のコンポーネントが付いているものを検索 | 【ハルシオンブログ】配列の要素を範囲指定で取得する »
コメント
| h o m e |