Unity iOS TestFlightアップロードエラー解決 - Asset validation failed (90206) Invalid Bundle
Unity iOS TestFlightアップロードエラー解決 - Asset validation failed (90206) Invalid Bundle
Build Error シリーズ (7 / 8)
- Unity Build イシュー解決まとめ - ID 238, Strip Engine Code, cs0246
- Unity - xcworkspace が生成されない問題の解決
- Unity Build イシュー解決まとめ - Gradle build failed, type initializer exception
- Unity Android Permission が削除されない問題の解決方法
- Unity Androidビルドエラー解決 - DexArchiveMergerException & MultiDex
- Unity iOSビルドエラー解決 - Microphone Usage Description & BeeBuildPostprocessor
- Unity iOS TestFlightアップロードエラー解決 - Asset validation failed (90206) Invalid Bundle
- Unity Addressableエラー解決 - RuntimeData is null, Invalid path in TextDataProvider
主要エラー現象分析
- Transporterを使用してTestFlightにアップロードしようとしたところ、次のようなエラーが発生しました。
1
2
Asset validation failed (90206)
Invalid Bundle. The bundle at 'TOYVERSE.app/Frameworks/UnityFramework.framework' contains disallowed file 'Frameworks'.(ID: 54a900bb-b251-492a-bed7-ee556a02d857)
- 惨憺たる痕跡…
解決方法
- stack overflowのスレッドを確認
- UnityプロジェクトをビルドしたXcodeプロジェクトの
xcworkspaceに入って、Unity-iPhone appとUnityFrameworkそれぞれの Build Settings でembedを検索すると - Always Embed Swift Standard Libraries が見えるはずです。これが Yes になっている場合、アップロードに失敗する可能性が非常に高いです。
- したがって、Unityビルドスクリプトである PostProcessBuild で後処理を通じてこの2つを無効化しましょう。
1
2
3
4
5
6
7
8
9
10
11
...
foreach (var targetGuid in new[] { mainTargetGuid, project.GetUnityFrameworkTargetGuid() })
{
project.SetBuildProperty(targetGuid, "ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES", "No");
project.SetBuildProperty(targetGuid, "LD_RUNPATH_SEARCH_PATHS", "$(inherited) /usr/lib/swift @executable_path/Frameworks");
//project.AddBuildProperty(targetGuid, "LD_RUNPATH_SEARCH_PATHS", "/usr/lib/swift");
}
project.SetBuildProperty(mainTargetGuid, "ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES", "No");
...
- 再度ビルドしてアップロードすれば成功!
ビルド後処理の全コード
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
class PBR : IPostprocessBuildWithReport
{
public int callbackOrder { get { return 0; } }
public void OnPostprocessBuild(BuildReport report)
{
if (report.summary.platform == BuildTarget.iOS)
{
Debug.Log("OnPostProceeBuild");
string projectPath = report.summary.outputPath + "/Unity-iPhone.xcodeproj/project.pbxproj";
var entitlementFilePath = "Entitlements.entitlements";
var project = new PBXProject();
project.ReadFromFile(projectPath);
var manager = new ProjectCapabilityManager(projectPath, entitlementFilePath, null, project.GetUnityMainTargetGuid());
manager.AddPushNotifications(true);
manager.AddAssociatedDomains(new string[] { "applinks:nkmb.adj.st" });// Universal-Link対応。
manager.WriteToFile();
var mainTargetGuid = project.GetUnityMainTargetGuid();
project.SetBuildProperty(mainTargetGuid, "ENABLE_BITCODE", "NO");
// Enterprise でのみ一時的に追加しておいたコードです。
// Sign In With Apple FrameworkはEnterpriseで有効化されないためXcodeビルドエラー発生
// Supported Destinations にiPadサポートを除外するコード
// 1 はiPhoneを意味する。
//project.SetBuildProperty(mainTargetGuid, "TARGETED_DEVICE_FAMILY", "1"); // 1 corresponds to iPhone
project.RemoveFrameworkFromProject(mainTargetGuid, "SIGN_IN_WITH_APPLE");
project.SetBuildProperty(mainTargetGuid, "CODE_SIGN_ENTITLEMENTS", entitlementFilePath);
project.AddFrameworkToProject(mainTargetGuid, "UserNotifications.framework", false);
foreach (var targetGuid in new[] { mainTargetGuid, project.GetUnityFrameworkTargetGuid() })
{
project.SetBuildProperty(targetGuid, "ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES", "No");
project.SetBuildProperty(targetGuid, "LD_RUNPATH_SEARCH_PATHS", "$(inherited) /usr/lib/swift @executable_path/Frameworks");
//project.AddBuildProperty(targetGuid, "LD_RUNPATH_SEARCH_PATHS", "/usr/lib/swift");
}
project.SetBuildProperty(mainTargetGuid, "ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES", "No");
#if DEV
// // instrument test
// // Enable 'get-task-allow' for Debug configuration
// project.SetBuildProperty(target, "GCC_GENERATE_DEBUGGING_SYMBOLS", "YES");
// project.SetBuildProperty(target, "ENABLE_TESTABILITY", "YES");
//
// project.WriteToFile(projectPath);
//
// // Fix the 'get-task-allow' error by enabling debugging in the entitlements file
// string entitlementsContents = System.IO.File.ReadAllText("/Users/YOUR_USERNAME/Xcode_dev/Entitlements.entitlements");
//
// // Make sure the debugging entitlement is present
// if (!entitlementsContents.Contains("<key>get-task-allow</key>"))
// {
// // Add the entitlement for debugging
// entitlementsContents = entitlementsContents.Replace("</dict>", "<key>get-task-allow</key><true/></dict>");
// System.IO.File.WriteAllText("/Users/YOUR_USERNAME/Xcode_dev/Entitlements.entitlements", entitlementsContents);
// }
#endif
}
}
}
[PostProcessBuild(callbackOrder:999)]
public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject)
{
#if UNITY_IPHONE
if (target == BuildTarget.iOS)
{
var projectPath = PBXProject.GetPBXProjectPath(pathToBuiltProject);
var project = new PBXProject();
Debug.Log($"Post Process Build callback : {projectPath}");
project.ReadFromString(File.ReadAllText(projectPath));
// Unity2019.3以降のUnityFramework分離対応
project.AddFrameworkToProject(project.GetUnityMainTargetGuid(), "UnityFramework.framework", false);
// iOS14対応
var frameworkTarget = project.GetUnityFrameworkTargetGuid();
project.AddFrameworkToProject(frameworkTarget, "AppTrackingTransparency.framework", true);
project.AddFrameworkToProject(frameworkTarget, "AdSupport.framework", true);
string infoPlistPath = pathToBuiltProject + "/Info.plist";
PlistDocument plistDoc = new PlistDocument();
plistDoc.ReadFromFile(infoPlistPath);
if (plistDoc.root != null)
{
plistDoc.root.SetBoolean("ITSAppUsesNonExemptEncryption", false);
var locale = new string[] { "en", "ja" };
var mainTargetGuid = project.GetUnityMainTargetGuid();
var array = plistDoc.root.CreateArray("CFBundleLocalizations");
foreach (var localization in locale)
{
array.AddString(localization);
}
plistDoc.root.SetString("NSUserTrackingUsageDescription", "Please allow permission to provide service and personalized marketing. It will be used only for the purpose of providing personalized advertising based on Apple's policy.");
// var entry = LocalizationSettings.StringDatabase.GetTableEntryAsync("LocalizeTable", "LZ_SRT_038");
// if (entry.IsDone)
// {
// var comment = entry.Result.Entry.GetMetadata<Comment>();
// var sharedEntry = entry.Result.Table.SharedData.GetEntry("LZ_SRT_038");
// var sharedComment = sharedEntry.Metadata.GetMetadata<Comment>();
// plistDoc.root.SetString("NSUserTrackingUsageDescription", sharedComment.CommentText);
// }
//plistDoc.root.SetString("NSUserTrackingUsageDescription", sharedComment);
plistDoc.WriteToFile(projectPath);
for (int i = 0; i < locale.Length; i++)
{
var guid = project.AddFolderReference(Application.dataPath + string.Format("/Editor/iOS/Localization/{0}.lproj", locale[i]), string.Format("{0}.lproj", locale[i]), PBXSourceTree.Source);
project.AddFileToBuild(mainTargetGuid, guid);
}
// 日本語に設定
//plistDoc.root.SetString("CFBundleDevelopmentRegion", "en");
// iOS14 AppTrackingポップアップの表示用
//var attMessage = StringManager.GetLZString("LZ_SRT_038") ?? "Localize is null";
//var attMessage = "Please allow permission to provide service and personalized marketing. It will be used only for the purpose of providing personalized advertising based on Apple's policy.";
//var attMessage = "att tracking test";
//var attMessage = "許可をした場合、本サービスで収集したお客様の情報をアプリの品質の向上に役立たせていただきます。" +
// "\n今後のサービス改善のため、トラッキングの設定をお願いします。" +
// "\n※トラッキングの設定は端末の設定からいつでも変更可能です。";
//var info = new UnityEngine.Localization.Platform.iOS.AppInfo();
//UnityEngine.Localization.Platform.iOS.AppInfo appInfo = info;
//var attMessage = info.UserTrackingUsageDescription.ToString();
//plistDoc.root.SetString("NSUserTrackingUsageDescription", attMessage);
// Firebase利用のためBackground mode設定が必要
PlistElementArray backgroundModes;
if (plistDoc.root.values.ContainsKey("UIBackgroundModes"))
{
backgroundModes = plistDoc.root["UIBackgroundModes"].AsArray();
}
else
{
backgroundModes = plistDoc.root.CreateArray("UIBackgroundModes");
}
backgroundModes.AddString("remote-notification");
plistDoc.WriteToFile(infoPlistPath);
}
else
{
Debug.LogError("ERROR: Can't open " + infoPlistPath);
}
project.WriteToFile(projectPath);
}
#endif
}
この記事は著者の CC BY 4.0 ライセンスの下で提供されています。





