Unity Xcode アーカイブ、 ipa作成自動化
UnityでXcodeからipa出力までの各設定の自動化をやってみた。
できた。
※ 勘で書いた部分もあるので注意。
参考
XcodeAPIの使い方
CIなどを使用するときに必要な値を確認する方法
UnityプロジェクトをJenkinsを使用してXCode8対応した
Unityでbashを利用する
xcodebuildでipa作成 -exportOptionsPlist対応版
流れ
- 1 exportOptions.plist作成、DEVELOPMENT_TEAMの10桁のコードを確認。
- 2 下記コードの
var ipa_plist = "path/to/exportOptions.plist";
の部分を作成したplistのパスに変更。pbx.SetBuildProperty(targetGuid, "DEVELOPMENT_TEAM", "xxxxxxxxxx");
のxの部分に10桁のコードを設定。 - 3 iOSビルド後に、OnPostprocessBuildが呼ばれる
- 4 ProjectSettingでXcodeのプロジェクトを書き換える
- 5 PlistSettingでplistを書き換える
- 6 AutomationCreatorで、automation.commandという自動化用bashスクリプトを作成し、
chmod -x
で実行権限を付与。 - 7 生成されたプロジェクト内のautomation.commandをダブルクリックで実行
- 8 hoge.xcarchiveとhoge.ipaが作成される
XcodeProjectUpdater.cs
#if UNITY_IOS using UnityEngine; using UnityEditor; using UnityEditor.Callbacks; using UnityEditor.iOS.Xcode; using System.IO; using System.Collections; using System.Diagnostics; // http://kan-kikuchi.hatenablog.com/entry/XcodeAPI public class XcodeProjectUpdater { [PostProcessBuild(100)] // layer 100 小さい方が先に実行 static void OnPostprocessBuild(BuildTarget buildTarget, string path) { if (buildTarget != BuildTarget.iOS) return; UnityEngine.Debug.Log ("xcode project update onpostprocess!"); ProjectSetting (path); PlistSetting (path); AutomationCreator (path, "hoge"); } static void AutomationCreator(string path, string output_name) { var cmd_cd = "cd `dirname $0`"; var camera_capture_path = Path.Combine (path, "Classes/Unity/CameraCapture.mm"); var cmd_camera_reset = string.Format ("sed -i -e 's/!UNITY_TVOS/0/g' \"{0}\"", camera_capture_path); var xcodeproj_path = Path.Combine (path, "Unity-iPhone.xcodeproj"); output_name = Path.Combine (path, output_name); var cmd_archive = string.Format("xcodebuild -project \"{0}\" -scheme \"Unity-iPhone\" archive -archivePath \"{1}\"", xcodeproj_path, output_name ); // http://qiita.com/roworks/items/7ef12acabf9679561d84 var ipa_plist = "path/to/exportOptions.plist"; var cmd_ipa = string.Format("xcodebuild -exportArchive -archivePath \"{0}.xcarchive\" -exportPath \"{0}.ipa\" -exportOptionsPlist \"{1}\"", output_name, ipa_plist ); var output_path = Path.Combine (path, "automation.command"); using(var sw = new StreamWriter(output_path)) { sw.WriteLine (cmd_cd); sw.WriteLine (cmd_camera_reset); sw.WriteLine (cmd_archive); sw.WriteLine (cmd_ipa); } BashProcess ("chmod +x " + output_path); } static void ProjectSetting(string path) { var pbxProjPath = PBXProject.GetPBXProjectPath (path); var pbx = new PBXProject (); pbx.ReadFromString (File.ReadAllText (pbxProjPath)); var targetGuid = pbx.TargetGuidByName (PBXProject.GetUnityTargetName ()); pbx.SetBuildProperty (targetGuid, "ENABLE_BITCODE", "NO"); pbx.SetBuildProperty (targetGuid, "ARCHS", "arm64"); pbx.SetBuildProperty (targetGuid, "VALID_ARCHS", "arm64"); pbx.SetBuildProperty (targetGuid, "IPHONEOS_DEPLOYMENT_TARGET", "9.0"); // http://qiita.com/Akira_Kido_N/items/25ffd68cade64ecade2e // http://qiita.com/altemina/items/c4747f26615792495a97 pbx.SetBuildProperty(targetGuid, "DEVELOPMENT_TEAM", "xxxxxxxxxx"); // 10桁のコード File.WriteAllText (pbxProjPath, pbx.WriteToString ()); } static void PlistSetting(string path) { var pListPath = Path.Combine (path, "Info.plist"); var plist = new PlistDocument (); plist.ReadFromFile (pListPath); #region ローカライズ 日本語 plist.root.SetString ("CFBundleDevelopmentRegion", "ja_JP"); // plist.root.CreateDict ("CFBundleLocalizations"); var locallization = plist.root.CreateArray ("CFBundleLocalizations"); locallization.AddString ("ja"); #endregion plist.WriteToFile (pListPath); } static bool isWorking = false; // http://smartgames.hatenablog.com/entry/2016/06/21/230714 static void BashProcess(string cmd) { if (isWorking) { UnityEngine.Debug.Log ("working."); return; } isWorking = true; var p = new Process (); p.StartInfo.FileName = "/bin/bash"; p.StartInfo.Arguments = "-c \" " + cmd + " \""; p.StartInfo.UseShellExecute = false; p.StartInfo.RedirectStandardOutput = true; p.Start (); var output = p.StandardOutput.ReadToEnd (); p.WaitForExit (); p.Close (); isWorking = false; UnityEngine.Debug.Log (output); } } #endif // UNITY_IOS