62
Unity に於ける iOS ビルド自動化の おはなし【実践編】 2014.10.30 (Thu) / Unity 勉強会 vol.26 株式会社キッズスター システムデベロプメントチーム リーダー 森 哲哉

Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

Embed Size (px)

DESCRIPTION

TechBuzzSpace で開催された「第26回 Unity 勉強会」での発表資料です。 Unity に於ける iOS のビルド自動化について語りました。

Citation preview

Page 1: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

Unity に於ける iOS ビルド自動化の おはなし【実践編】

2014.10.30 (Thu) / Unity 勉強会 vol.26

株式会社キッズスター システムデベロプメントチーム リーダー

森 哲哉

Page 2: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

こんばんは!

Page 3: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

「またお前か」 とか言わない。もんりぃですっ!

Page 4: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

今日のテーマ

Page 5: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会
Page 6: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

と、いうわけで

ビルド のおはなしです

Page 7: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

おしながき

Page 8: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

おしながき

• 自己紹介

• 前置き

• やること

• やりかた

Page 9: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

自己紹介

Page 10: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

$ whoami

• “森 哲哉” と申します。

• a.k.a: もんりぃ / T: @monry / F: monry84

• 30歳 / ♂ / O型 / 天秤座 / 既婚

• 趣味は「お酒」と「合唱」です。

Page 11: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

$ whoami• 大学を (自主的に) 卒業後、ベンチャーを転々。

• Web のフロントエンド、サーバサイドが得意。

• Unity 歴 1 年半くらい。

• AWS とキャッキャウフフするのも好きです。

• 絶賛 Shader のお勉強中。

Page 12: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

$ jobs• “株式会社キッズスター” って会社で働いてます。

• 未就学児~小学生のお子さまをお持ちのファミリーをターゲットにした、知育/教育に関わるアプリ・サービスを展開しております。

• お陰様で EdTech な知育分野に於いてNo.1 規模で展開しております!(当社調べw)

Page 13: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

$ ls -la apps/

なりきり!! ごっこランド

パズル&テイルズおかしのくにを つくるのじゃ!!

なりきり!! アイスクリーム 屋さんごっこ

なりきり!! ママごっこ

お弁当をつくろう!

おかしの家を つくろう!

ハンバーガー やさんごっこ

飛行機を 組み立てよう!

i18n i18n i18n

i18n

ゆかいな お花屋さん

App Sto

re / Goo

gle Play

カテゴリランキング1位

多数獲得!!!

Page 14: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

前置き

Page 15: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

環境• 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)

Page 16: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

今日 喋るコト

• “Build” ボタンを押した以降の話

• 極力 Xcode を操作しないって話

• PostProcessBuild な話

Page 17: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

今日 喋らないこと

• Native Plugin の話

• iTunes Connect での申請の話

Page 18: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

やること

Page 19: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

Unity ⇒ Xcode

Page 20: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

Unity ⇒ Xcode

このボタンを押すと…

Page 21: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

Unity ⇒ Xcode

コレを雛形にして…

Page 22: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

Unity ⇒ Xcode

こんなのが出力され…

Page 23: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

Unity ⇒ Xcode

こいつにプロジェクト情報とかが定義される

Page 24: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

Archive

Page 25: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

Pre Archive• アイコン設定

• ARC な Native Plugin へ -fobjc-arc の設定

• Other Linker Flags の設定

• 追加 Framework の設定

• アイコン下のアプリ名設定

• URLSchemes 設定

Page 26: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

Packaging

コレを出力する

Page 27: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

Packaging

Xcode Project と Provisioning Profile が重要

×

Page 28: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

Packaging

Xcode のメニューから [ Product ] > [ Archive ]

Page 29: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

Packaging

Organizer で [ Export ] ボタン押して…

Page 30: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

Packaging

テスターさんに配る用の ipa 作ったりとかね。

Page 31: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

ここまでの作業を 職人が丹精込めて 手作業で。

Page 32: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

(/#-_-)/~┻┻〃ヤッテラレッカ

Page 33: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

じゃあ…

Page 34: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

いつ自動化するの!?

Page 35: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

今でしょ!

Page 36: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

やりかた

Page 37: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

Export Xcode Project

Page 38: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

Export Xcode Project

UnityEditor.BuildPipeline.BuildPlayer( string[] levels, string locationPathName, UnityEditor.BuildTarget target, UnityEditor.BuildOptions options );

先ずは基本から

Page 39: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

Export Xcode Project

BuildPipeline.BuildPlayer( new string[] { "Main.scene" }, "/Users/monry/SampleProject", BuildTarget.iPhone, BuildOptions.Development | BuildOptions.AllowDebugging );

Example

これで Xcode Project が出力される

Page 40: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

ココから先は PostProcessBuild で処理する

Page 41: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

Archive

Page 42: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

Archive

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();

先ずは xcodebuild コマンド実行

Provisioning の ID は iPhone 構成ユーティリティとかで調べる感じで。

Page 43: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

Archive

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();

続いて xcrun コマンド実行

プロジェクト名は、Player Settings の Product Name を指定する

Page 44: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

アイコン設定

Page 45: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

アイコン設定

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\\}\n\t\\],", "\t},\n\t\t\t{\n\t\t\"size\" : \"60x60\",\n\t\t\"idiom\" : \"iphone\",\n\t\t\"filename\" : \"Icon-180.png\",\n\t\t\"scale\" : \"3x\"\n\t}\n\t]," ); File.WriteAllText( Path.Combine( path, "Unity-iPhone/Images.xcassets/AppIcon.appiconset/Contents.json" ), jsonText );

iPhone 6/6 Plus 用のアイコンが抜けるので。

最新 (4.5.5) では対応済かも? (調べてない。)

Page 46: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

-fobjc-arc 設定

Page 47: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

-fobjc-arc 設定

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"); } }

Xcode Editor for Unity を使う

Unity は Non-ARC なので、ARC な Native Plugin にはフラグを付けてあげる必要がある。

Page 48: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

Other Linker Flags 設定

Page 49: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

Other Linker Flags 設定

XCProject project = new UnityEditor.XCodeEditor.XCProject("/path/to/export"); string[] flagNameList = new string[] { "-ObjC", "-all_load", ... }; foreach (string flagName in flagNameList) { project.AddOtherLDFlags(flagName); }

同じく Xcode Editor for Unity 使う

外部 SDK とか使うときに必要だったりする。

Page 50: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

追加 Framework の設定

Page 51: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

追加 Framework の設定

XCProject project = new UnityEditor.XCodeEditor.XCProject("/path/to/export"); project.ApplyMod(Path.Combine(Application.dataPath, "path/to/projmods"));

やっぱり Xcode Editor for Unity 使う

.projmods なるファイルを食わせる

Page 52: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

追加 Framework の設定

{ "group": "", "patches": [], "libs": [], "librarysearchpaths": [], "frameworksearchpaths": [], "frameworks": [ "Security.framework", "CoreData.framework", ], "headerpaths": [], "files": [], "folders": [], "excludes": ["^.*\\.meta$", "^.*\\.mdown^", "^.*\\.pdf$"] }

hoge.projmods のサンプル

JSON 形式で記述。 状況に応じて他のキーも設定したりとか。

Page 53: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

アイコン下のアプリ名

Page 54: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

アイコン下のアプリ名

// Unity-iPhone/en.lproj/InfoPlist.strings CFBundleDisplayName = "HogeFuga";

// Unity-iPhone/ja.lproj/InfoPlist.strings CFBundleDisplayName = "ほげふが";

先ずは InfoPlist.strings を作る

ファイル名とかはコレじゃ無くても OK

Page 55: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

アイコン下のアプリ名

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) ); }

InfoPlist.strings を VariantGroup に追加

VariantGroup 対応版がコチラにございます。 KnownRegion を追加しないとダメ。

Page 56: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

URLSchemes 設定

Page 57: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

URLSchemes 設定

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);

info.plist (XML) をゴリゴリ書き換える

赤文字のトコは、書き換えてね。

Page 58: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

おまけ

Page 59: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

おまけ• ビルドした ipa を DeployGate に自動 PUSH すると、オシャレ!

• 更にその結果を ChatWork なり Slack なりに 自動 POST すると、もっとオシャレ!!

• 更に更に、ココまでを Jenkins オジサンとかにお願いすると、最高にオシャレ!!!

Page 60: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

まとめ

Page 61: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

まとめ

• PostProcessBuild で、基本的な設定を置換

• Build → Archive → Deploy も自動化しよう!

Page 62: Unity に於ける iOS ビルド自動化のおはなし - 20141030 第26回 Unity 勉強会

Thank you foryour attention !