More Related Content
Similar to Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会 (20)
More from Mori Tetsuya (20)
Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会
- 1. Unity に於ける
iOS ビルド自動化の
おはなし【実践編】
2014.10.30 (Thu) / Unity 勉強会 vol.26
株式会社キッズスター
システムデベロプメントチーム リーダー
森 哲哉
- 10. $ whoami
• “森 哲哉” と申します。
• a.k.a: もんりぃ / T: @monry / F: monry84
• 30歳 / ♂ / O型 / 天秤座 / 既婚
• 趣味は「お酒」と「合唱」です。
- 11. $ whoami
• 大学を (自主的に) 卒業後、ベンチャーを転々。
• Web のフロントエンド、サーバサイドが得意。
• Unity 歴 1 年半くらい。
• AWS とキャッキャウフフするのも好きです。
• 絶賛 Shader のお勉強中。
- 12. $ jobs
• “株式会社キッズスター” って会社で働いてます。
• 未就学児~小学生のお子さまをお持ちの
ファミリーをターゲットにした、知育/教育に
関わるアプリ・サービスを展開しております。
• お陰様で EdTech な知育分野に於いて
No.1 規模で展開しております!(当社調べw)
- 13. $ ls -la apps/
なりきり!!
ごっこランド
パズル&テイルズ
おかしのくにを
つくるのじゃ!!
なりきり!!
アイスクリーム
屋さんごっこ
なりきり!!
ママごっこ
お弁当をつくろう!
おかしの家を
つくろう!
ハンバーガー
やさんごっこ
飛行機を
組み立てよう!
i18n i18n i18n
i18n
Google Play
/ グ1位
Store App ランキンゆかいな
カテゴリお花屋さん多数獲得!!!
- 15. 環境
• Operation System: OS X Yosemite
• Unity: 4.5.4f1 (Pro Only)
• Xcode: 6 (with Commind Line Tools)
• Platform: iOS
• Language: C#
• Other: Xcode Editor for Unity (forked by monry)
- 16. 今日 喋るコト
• “Build” ボタンを押した以降の話
• 極力 Xcode を操作しないって話
• PostProcessBuild な話
- 17. 今日 喋らないこと
• Native Plugin の話
• iTunes Connect での申請の話
- 25. Pre Archive
• アイコン設定
• ARC な Native Plugin へ -fobjc-arc の設定
• Other Linker Flags の設定
• 追加 Framework の設定
• アイコン下のアプリ名設定
• URLSchemes 設定
- 38. Export Xcode Project
先ずは基本から
UnityEditor.BuildPipeline.BuildPlayer(
string[] levels,
string locationPathName,
UnityEditor.BuildTarget target,
UnityEditor.BuildOptions options
);
- 39. Export Xcode Project
Example
BuildPipeline.BuildPlayer(
new string[] { "Main.scene" },
"/Users/monry/SampleProject",
BuildTarget.iPhone,
BuildOptions.Development
| BuildOptions.AllowDebugging
);
これで Xcode Project が出力される
- 42. Archive
先ずは xcodebuild コマンド実行
System.Diagnostics.Process process = new
System.Diagnostics.Process();
process.StartInfo.FileName = "/usr/bin/xcodebuild";
process.StartInfo.Arguments = string.Format(
"-project "{0}/Unity-iPhone.xcodeproj" -sdk iphoneos -target
"Unity-iPhone" -configuration Release clean build
CODE_SIGN_IDENTITY="iPhone Distribution" PROVISIONING_PROFILE=
"{1}"",
"/path/to/export",
"Provisioning Profile ID"
);
process.StartInfo.CreateNoWindow = true;
process.Start();
process.WaitForExit();
process.Close();
Provisioning の ID は iPhone 構成ユーティリティ
とかで調べる感じで。
- 43. Archive
続いて xcrun コマンド実行
System.Diagnostics.Process process = new
System.Diagnostics.Process();
process.StartInfo.FileName = "/usr/bin/xcrun";
process.StartInfo.Arguments = string.Format(
"-sdk iphoneos PackageApplication "{0}/build/{1}.app" -o
"{0}/build/Unity-iPhone.ipa" --embed "{2}.mobileprovision"",
"/path/to/export",
"SampleProject", // プロジェクト名
"Provisioning Profile ID"
);
process.StartInfo.CreateNoWindow = true;
process.Start();
process.WaitForExit();
process.Close();
プロジェクト名は、Player Settings の
Product Name を指定する
- 45. アイコン設定
iPhone 6/6 Plus 用のアイコンが抜けるので。
string path = "/path/to/export";
File.Copy(
Path.Combine(Application.dataPath, "/Path/to/Icon-180.png"),
Path.Combine(path, "Unity-iPhone/Images.xcassets/AppIcon.appiconset/Icon-180.png"),
true
);
string jsonText = File.ReadAllText(
Path.Combine(path, "Unity-iPhone/Images.xcassets/AppIcon.appiconset/Contents.json")
);
jsonText = Regex.Replace(
jsonText,
"t}nt],",
"t},nttt{ntt"size" : "60x60",ntt"idiom" : "iphone",ntt"filename" :
"Icon-180.png",ntt"scale" : "3x"nt}nt],"
);
File.WriteAllText(
Path.Combine(
path,
"Unity-iPhone/Images.xcassets/AppIcon.appiconset/Contents.json"
),
jsonText
);
最新 (4.5.5) では対応済かも? (調べてない。)
- 47. -fobjc-arc 設定
Xcode Editor for Unity を使う
XCProject project = new
UnityEditor.XCodeEditor.XCProject("/path/to/export");
string[] filePathList = new string[] { "/path/to/
file1", "/path/to/file2", ... };
foreach (string filePath in filePathList) {
PBXBuildFile buildFile =
project.GetBuildFile(project.GetFile(filePath));
if (null != buildFile) {
buildFile.AddCompilerFlag("-fobjc-arc");
}
}
Unity は Non-ARC なので、ARC な Native
Plugin にはフラグを付けてあげる必要がある。
- 49. Other Linker Flags 設定
同じく Xcode Editor for Unity 使う
XCProject project = new
UnityEditor.XCodeEditor.XCProject("/path/to/export");
string[] flagNameList = new string[] { "-ObjC", "-
all_load", ... };
foreach (string flagName in flagNameList) {
project.AddOtherLDFlags(flagName);
}
外部 SDK とか使うときに必要だったりする。
- 51. 追加 Framework の設定
やっぱり Xcode Editor for Unity 使う
XCProject project = new
UnityEditor.XCodeEditor.XCProject("/path/to/export");
project.ApplyMod(Path.Combine(Application.dataPath,
"path/to/projmods"));
.projmods なるファイルを食わせる
- 52. 追加 Framework の設定
hoge.projmods のサンプル
{
"group": "",
"patches": [],
"libs": [],
"librarysearchpaths": [],
"frameworksearchpaths": [],
"frameworks": [
"Security.framework",
"CoreData.framework",
],
"headerpaths": [],
"files": [],
"folders": [],
"excludes": ["^.*.meta$", "^.*.mdown^", "^.*.pdf$"]
}
JSON 形式で記述。
状況に応じて他のキーも設定したりとか。
- 54. アイコン下のアプリ名
先ずは InfoPlist.strings を作る
// Unity-iPhone/en.lproj/InfoPlist.strings
CFBundleDisplayName = "HogeFuga";
// Unity-iPhone/ja.lproj/InfoPlist.strings
CFBundleDisplayName = "ほげふが";
ファイル名とかはコレじゃ無くても OK
- 55. アイコン下のアプリ名
InfoPlist.strings を VariantGroup に追加
XCProject project = new UnityEditor.XCodeEditor.XCProject("/path/to/export");
PBXVariantGroup infoPlist = project.GetVariantGroup("InfoPlist.strings",
null, project.GetGroup("Supporting Files"));
string[] languageCodeList = new string[] { "ja", "en" };
foreach (string languageCode in languageCodeList) {
project.project.AddKnownRegion(languageCode);
project.AddFile(
Path.Combine(this.path, string.Format("Unity-iPhone/{0}.lproj/
InfoPlist.strings", languageCode)),
infoPlist,
"SOURCE_ROOT",
true,
false,
string.Format("{0}.lproj/InfoPlist.strings", languageCode)
);
}
VariantGroup 対応版がコチラにございます。
KnownRegion を追加しないとダメ。
- 57. URLSchemes 設定
info.plist (XML) をゴリゴリ書き換える
XmlDocument infoPlist = new XmlDocument();
infoPlist.Load(Path.Combine("/path/to/export", "Info.plist"));
XmlNode infoPlistBaseNode = this.infoPlist.SelectSingleNode("/plist/dict");
// 一つ分の URL Type を表現するノードを構築
XmlElement _dict = infoPlist.CreateElement("dict");
_dict.AppendChild(infoPlist.CreateSimpleTextNode("key", "CFBundleTypeRole"));
_dict.AppendChild(infoPlist.CreateSimpleTextNode("string", "Editor"));
_dict.AppendChild(infoPlist.CreateSimpleTextNode("key", "CFBundleURLName"));
_dict.AppendChild(infoPlist.CreateSimpleTextNode("string", "tv.kidsstar.app.${PRODUCT_NAME:rfc1034identifier}"));
_dict.AppendChild(infoPlist.CreateSimpleTextNode("key", "CFBundleURLSchemes"));
XmlElement _array = infoPlist.CreateElement("array");
_array.AppendChild(infoPlist.CreateSimpleTextNode("string", "tv.kidsstar.app.${PRODUCT_NAME:rfc1034identifier}"));
_dict.AppendChild(_array);
// 作ったノードを key: CFBundleURLTypes の要素として追加
XmlNode _CFBundleURLTypesNode = infoPlist.SelectSingleNode("/plist/dict/array[preceding-sibling::key[.=
"CFBundleURLTypes"]][1]");
if (null == _CFBundleURLTypesNode) {
infoPlistBaseNode.AppendChild(infoPlist.CreateSimpleTextNode("key", "CFBundleURLTypes"));
_CFBundleURLTypesNode = infoPlist.CreateElement("array");
infoPlistBaseNode.AppendChild(_CFBundleURLTypesNode);
}
_CFBundleURLTypesNode.AppendChild(_dict);
赤文字のトコは、書き換えてね。
- 59. おまけ
• ビルドした ipa を DeployGate に自動 PUSH
すると、オシャレ!
• 更にその結果を ChatWork なり Slack なりに
自動 POST すると、もっとオシャレ!!
• 更に更に、ココまでを Jenkins オジサンとかに
お願いすると、最高にオシャレ!!!