SlideShare a Scribd company logo
1 of 62
Download to read offline
Unity に於ける 
iOS ビルド自動化の 
おはなし【実践編】 
2014.10.30 (Thu) / Unity 勉強会 vol.26 
株式会社キッズスター 
システムデベロプメントチーム リーダー 
森 哲哉
こんばんは!
「またお前か」 
もとんかり言ぃわでなすいっ。!
今日のテーマ
と、いうわけで 
ビルド 
のおはなしです
おしながき
おしながき 
• 自己紹介 
• 前置き 
• やること 
• やりかた
自己紹介
$ whoami 
• “森 哲哉” と申します。 
• a.k.a: もんりぃ / T: @monry / F: monry84 
• 30歳 / ♂ / O型 / 天秤座 / 既婚 
• 趣味は「お酒」と「合唱」です。
$ whoami 
• 大学を (自主的に) 卒業後、ベンチャーを転々。 
• Web のフロントエンド、サーバサイドが得意。 
• Unity 歴 1 年半くらい。 
• AWS とキャッキャウフフするのも好きです。 
• 絶賛 Shader のお勉強中。
$ jobs 
• “株式会社キッズスター” って会社で働いてます。 
• 未就学児~小学生のお子さまをお持ちの 
ファミリーをターゲットにした、知育/教育に 
関わるアプリ・サービスを展開しております。 
• お陰様で EdTech な知育分野に於いて 
No.1 規模で展開しております!(当社調べw)
$ ls -la apps/ 
なりきり!! 
ごっこランド 
パズル&テイルズ 
おかしのくにを 
つくるのじゃ!! 
なりきり!! 
アイスクリーム 
屋さんごっこ 
なりきり!! 
ママごっこ 
お弁当をつくろう! 
おかしの家を 
つくろう! 
ハンバーガー 
やさんごっこ 
飛行機を 
組み立てよう! 
i18n i18n i18n 
i18n 
Google Play 
/ グ1位 
Store App ランキンゆかいな 
カテゴリお花屋さん多数獲得!!!
前置き
環境 
• 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)
今日 喋るコト 
• “Build” ボタンを押した以降の話 
• 極力 Xcode を操作しないって話 
• PostProcessBuild な話
今日 喋らないこと 
• Native Plugin の話 
• iTunes Connect での申請の話
やること
Unity ⇒ Xcode
Unity ⇒ Xcode 
このボタンを押すと…
Unity ⇒ Xcode 
コレを雛形にして…
Unity ⇒ Xcode 
こんなのが出力され…
Unity ⇒ Xcode 
こいつにプロジェクト情報とかが定義される
Archive
Pre Archive 
• アイコン設定 
• ARC な Native Plugin へ -fobjc-arc の設定 
• Other Linker Flags の設定 
• 追加 Framework の設定 
• アイコン下のアプリ名設定 
• URLSchemes 設定
Packaging 
コレを出力する
Packaging 
× 
Xcode Project と Provisioning Profile が重要
Packaging 
Xcode のメニューから [ Product ] > [ Archive ]
Packaging 
Organizer で [ Export ] ボタン押して…
Packaging 
テスターさんに配る用の ipa 作ったりとかね。
ここまでの作業を 
職人が丹精込めて 
手作業で。
(/#-_-)/~┻┻〃ヤッテラレッカ
じゃあ…
いつ自動化するの!?
今でしょ!
やりかた
Export Xcode Project
Export Xcode Project 
先ずは基本から 
UnityEditor.BuildPipeline.BuildPlayer( 
string[] levels, 
string locationPathName, 
UnityEditor.BuildTarget target, 
UnityEditor.BuildOptions options 
);
Export Xcode Project 
Example 
BuildPipeline.BuildPlayer( 
new string[] { "Main.scene" }, 
"/Users/monry/SampleProject", 
BuildTarget.iPhone, 
BuildOptions.Development 
| BuildOptions.AllowDebugging 
); 
これで Xcode Project が出力される
ココから先は 
PostProcessBuild 
で処理する
Archive
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 構成ユーティリティ 
とかで調べる感じで。
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 を指定する
アイコン設定
アイコン設定 
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) では対応済かも? (調べてない。)
-fobjc-arc 設定
-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 にはフラグを付けてあげる必要がある。
Other Linker Flags 設定
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 とか使うときに必要だったりする。
追加 Framework の設定
追加 Framework の設定 
やっぱり Xcode Editor for Unity 使う 
XCProject project = new 
UnityEditor.XCodeEditor.XCProject("/path/to/export"); 
project.ApplyMod(Path.Combine(Application.dataPath, 
"path/to/projmods")); 
.projmods なるファイルを食わせる
追加 Framework の設定 
hoge.projmods のサンプル 
{ 
"group": "", 
"patches": [], 
"libs": [], 
"librarysearchpaths": [], 
"frameworksearchpaths": [], 
"frameworks": [ 
"Security.framework", 
"CoreData.framework", 
], 
"headerpaths": [], 
"files": [], 
"folders": [], 
"excludes": ["^.*.meta$", "^.*.mdown^", "^.*.pdf$"] 
} 
JSON 形式で記述。 
状況に応じて他のキーも設定したりとか。
アイコン下のアプリ名
アイコン下のアプリ名 
先ずは InfoPlist.strings を作る 
// Unity-iPhone/en.lproj/InfoPlist.strings 
CFBundleDisplayName = "HogeFuga"; 
// Unity-iPhone/ja.lproj/InfoPlist.strings 
CFBundleDisplayName = "ほげふが"; 
ファイル名とかはコレじゃ無くても OK
アイコン下のアプリ名 
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 を追加しないとダメ。
URLSchemes 設定
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); 
赤文字のトコは、書き換えてね。
おまけ
おまけ 
• ビルドした ipa を DeployGate に自動 PUSH 
すると、オシャレ! 
• 更にその結果を ChatWork なり Slack なりに 
自動 POST すると、もっとオシャレ!! 
• 更に更に、ココまでを Jenkins オジサンとかに 
お願いすると、最高にオシャレ!!!
まとめ
まとめ 
• PostProcessBuild で、基本的な設定を置換 
• Build → Archive → Deploy も自動化しよう!
Thank you for 
your attention !

More Related Content

What's hot

日曜プログラマーが
1週間くらいで通信対戦ゲームを作ってみた
日曜プログラマーが
1週間くらいで通信対戦ゲームを作ってみた日曜プログラマーが
1週間くらいで通信対戦ゲームを作ってみた
日曜プログラマーが
1週間くらいで通信対戦ゲームを作ってみた
Yuusuke Takeuchi
 
Createjsについて@jsCafe20
Createjsについて@jsCafe20Createjsについて@jsCafe20
Createjsについて@jsCafe20
佐藤 俊太郎
 
Createjs jp study #4 20130726
Createjs jp study #4 20130726Createjs jp study #4 20130726
Createjs jp study #4 20130726
Seigo Tanaka
 

What's hot (20)

Android カスタムROMの作り方
Android カスタムROMの作り方Android カスタムROMの作り方
Android カスタムROMの作り方
 
日曜プログラマーが
1週間くらいで通信対戦ゲームを作ってみた
日曜プログラマーが
1週間くらいで通信対戦ゲームを作ってみた日曜プログラマーが
1週間くらいで通信対戦ゲームを作ってみた
日曜プログラマーが
1週間くらいで通信対戦ゲームを作ってみた
 
ポコロンダンジョンズを彩るアニメーションノウハウ
ポコロンダンジョンズを彩るアニメーションノウハウポコロンダンジョンズを彩るアニメーションノウハウ
ポコロンダンジョンズを彩るアニメーションノウハウ
 
低スペックPCでも動く!UE4の設定&歩き方
低スペックPCでも動く!UE4の設定&歩き方低スペックPCでも動く!UE4の設定&歩き方
低スペックPCでも動く!UE4の設定&歩き方
 
Createjsについて@jsCafe20
Createjsについて@jsCafe20Createjsについて@jsCafe20
Createjsについて@jsCafe20
 
UE4をレンダラとした趣味的スピード背景ルックデブ(UE4 Environment Art Dive)
UE4をレンダラとした趣味的スピード背景ルックデブ(UE4 Environment Art Dive)UE4をレンダラとした趣味的スピード背景ルックデブ(UE4 Environment Art Dive)
UE4をレンダラとした趣味的スピード背景ルックデブ(UE4 Environment Art Dive)
 
スマホ版ログレスにポストエフェクトシステムを導入した話
スマホ版ログレスにポストエフェクトシステムを導入した話スマホ版ログレスにポストエフェクトシステムを導入した話
スマホ版ログレスにポストエフェクトシステムを導入した話
 
UE4におけるキャラクタークラス設計
UE4におけるキャラクタークラス設計UE4におけるキャラクタークラス設計
UE4におけるキャラクタークラス設計
 
「おしゃべりゆかり」 MMDAgentDay 掲示資料
「おしゃべりゆかり」 MMDAgentDay 掲示資料「おしゃべりゆかり」 MMDAgentDay 掲示資料
「おしゃべりゆかり」 MMDAgentDay 掲示資料
 
UNIBOOK2執筆ガイドライン
UNIBOOK2執筆ガイドラインUNIBOOK2執筆ガイドライン
UNIBOOK2執筆ガイドライン
 
Unibook3執筆ガイドライン
Unibook3執筆ガイドラインUnibook3執筆ガイドライン
Unibook3執筆ガイドライン
 
おしゃべりゆかり 外部ツールによるMMDAgent操作
おしゃべりゆかり 外部ツールによるMMDAgent操作おしゃべりゆかり 外部ツールによるMMDAgent操作
おしゃべりゆかり 外部ツールによるMMDAgent操作
 
UE4で”MetaHumanを使わずに”耳なし芳一になる10の方法 | UE4 Character Art Dive Online
UE4で”MetaHumanを使わずに”耳なし芳一になる10の方法 | UE4 Character Art Dive OnlineUE4で”MetaHumanを使わずに”耳なし芳一になる10の方法 | UE4 Character Art Dive Online
UE4で”MetaHumanを使わずに”耳なし芳一になる10の方法 | UE4 Character Art Dive Online
 
UE4を使った映像制作 (UE4 Character Art Dive Online)
UE4を使った映像制作 (UE4 Character Art Dive Online)UE4を使った映像制作 (UE4 Character Art Dive Online)
UE4を使った映像制作 (UE4 Character Art Dive Online)
 
Unityでデスクトップマスコットを作ろう
Unityでデスクトップマスコットを作ろうUnityでデスクトップマスコットを作ろう
Unityでデスクトップマスコットを作ろう
 
UE4を用いた人間から狼男への変身表現法の解説
UE4を用いた人間から狼男への変身表現法の解説UE4を用いた人間から狼男への変身表現法の解説
UE4を用いた人間から狼男への変身表現法の解説
 
エターナらないゲーム開発
エターナらないゲーム開発エターナらないゲーム開発
エターナらないゲーム開発
 
【Unite 2017 Tokyo】WebGL:ゲームプラットフォームとしてのWebと現在と未来
【Unite 2017 Tokyo】WebGL:ゲームプラットフォームとしてのWebと現在と未来【Unite 2017 Tokyo】WebGL:ゲームプラットフォームとしてのWebと現在と未来
【Unite 2017 Tokyo】WebGL:ゲームプラットフォームとしてのWebと現在と未来
 
UE4ローカライズ事例 (UE4 Localization Deep Dive)
UE4ローカライズ事例 (UE4 Localization Deep Dive)UE4ローカライズ事例 (UE4 Localization Deep Dive)
UE4ローカライズ事例 (UE4 Localization Deep Dive)
 
Createjs jp study #4 20130726
Createjs jp study #4 20130726Createjs jp study #4 20130726
Createjs jp study #4 20130726
 

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

Titanium Mobile
Titanium MobileTitanium Mobile
Titanium Mobile
Naoya Ito
 
TestFlight自動化でらくらくチームテスト
TestFlight自動化でらくらくチームテストTestFlight自動化でらくらくチームテスト
TestFlight自動化でらくらくチームテスト
Yoichiro Sakurai
 
Css nite(2010.09.23)
Css nite(2010.09.23)Css nite(2010.09.23)
Css nite(2010.09.23)
Yoshiki Ushida
 
ドキュメンテーションを加速するストレスフリーの作図ツール『blockdiag』 jus2011年6月勉強会
ドキュメンテーションを加速するストレスフリーの作図ツール『blockdiag』 jus2011年6月勉強会ドキュメンテーションを加速するストレスフリーの作図ツール『blockdiag』 jus2011年6月勉強会
ドキュメンテーションを加速するストレスフリーの作図ツール『blockdiag』 jus2011年6月勉強会
Takayuki Shimizukawa
 
How To Build Last Fm For I Phone
How To Build Last Fm For I PhoneHow To Build Last Fm For I Phone
How To Build Last Fm For I Phone
Keisuke Hata
 

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

Firefoxosハンズオン
FirefoxosハンズオンFirefoxosハンズオン
Firefoxosハンズオン
 
ぶっとびケータイ+Firefox OS Apps
ぶっとびケータイ+Firefox OS Appsぶっとびケータイ+Firefox OS Apps
ぶっとびケータイ+Firefox OS Apps
 
Titanium Mobile
Titanium MobileTitanium Mobile
Titanium Mobile
 
TestFlight自動化でらくらくチームテスト
TestFlight自動化でらくらくチームテストTestFlight自動化でらくらくチームテスト
TestFlight自動化でらくらくチームテスト
 
Firefox OS アプリ開発
Firefox OS アプリ開発Firefox OS アプリ開発
Firefox OS アプリ開発
 
Unityの夕べ in Fukuoka
Unityの夕べ in FukuokaUnityの夕べ in Fukuoka
Unityの夕べ in Fukuoka
 
どこでも動くゲームを作るためのベタープラクティス
どこでも動くゲームを作るためのベタープラクティスどこでも動くゲームを作るためのベタープラクティス
どこでも動くゲームを作るためのベタープラクティス
 
Firefox Add-on SDK 入門
Firefox Add-on SDK 入門Firefox Add-on SDK 入門
Firefox Add-on SDK 入門
 
Css nite(2010.09.23)
Css nite(2010.09.23)Css nite(2010.09.23)
Css nite(2010.09.23)
 
Mashup Caravan in オープンソースカンファレンス2011 Hiroshima: infoScoop OpenSource
Mashup Caravan in オープンソースカンファレンス2011 Hiroshima: infoScoop OpenSourceMashup Caravan in オープンソースカンファレンス2011 Hiroshima: infoScoop OpenSource
Mashup Caravan in オープンソースカンファレンス2011 Hiroshima: infoScoop OpenSource
 
Flashup 11
Flashup 11Flashup 11
Flashup 11
 
ドキュメンテーションを加速するストレスフリーの作図ツール『blockdiag』 jus2011年6月勉強会
ドキュメンテーションを加速するストレスフリーの作図ツール『blockdiag』 jus2011年6月勉強会ドキュメンテーションを加速するストレスフリーの作図ツール『blockdiag』 jus2011年6月勉強会
ドキュメンテーションを加速するストレスフリーの作図ツール『blockdiag』 jus2011年6月勉強会
 
Firefox OS アプリケーション チュートリアル
Firefox OS アプリケーション チュートリアルFirefox OS アプリケーション チュートリアル
Firefox OS アプリケーション チュートリアル
 
Build 番号の自動更新スクリプトについて #cocoa_kansai
Build 番号の自動更新スクリプトについて #cocoa_kansaiBuild 番号の自動更新スクリプトについて #cocoa_kansai
Build 番号の自動更新スクリプトについて #cocoa_kansai
 
20120118 titanium
20120118 titanium20120118 titanium
20120118 titanium
 
Sencha touchのはじめかた
Sencha touchのはじめかたSencha touchのはじめかた
Sencha touchのはじめかた
 
Android Lecture #01 @PRO&BSC Inc.
Android Lecture #01 @PRO&BSC Inc.Android Lecture #01 @PRO&BSC Inc.
Android Lecture #01 @PRO&BSC Inc.
 
【更新版】20190628玉川大学脳トレ社会科学oTree演習編
【更新版】20190628玉川大学脳トレ社会科学oTree演習編【更新版】20190628玉川大学脳トレ社会科学oTree演習編
【更新版】20190628玉川大学脳トレ社会科学oTree演習編
 
How To Build Last Fm For I Phone
How To Build Last Fm For I PhoneHow To Build Last Fm For I Phone
How To Build Last Fm For I Phone
 
Xamarin.Forms概要
Xamarin.Forms概要Xamarin.Forms概要
Xamarin.Forms概要
 

More from Mori Tetsuya

Unity 5 の AssetBundle について (浅く) まとめてみた - 2015/05/22 第31回 Unity 勉強会
Unity 5 の AssetBundle について (浅く) まとめてみた - 2015/05/22 第31回 Unity 勉強会Unity 5 の AssetBundle について (浅く) まとめてみた - 2015/05/22 第31回 Unity 勉強会
Unity 5 の AssetBundle について (浅く) まとめてみた - 2015/05/22 第31回 Unity 勉強会
Mori Tetsuya
 
20140711 MySQL Casual Talks vol.6 / 続・Amazon RDS Casual Talks
20140711 MySQL Casual Talks vol.6 / 続・Amazon RDS Casual Talks20140711 MySQL Casual Talks vol.6 / 続・Amazon RDS Casual Talks
20140711 MySQL Casual Talks vol.6 / 続・Amazon RDS Casual Talks
Mori Tetsuya
 

More from Mori Tetsuya (20)

GraphView のすゝめ / Introduction of GraphView
GraphView のすゝめ / Introduction of GraphViewGraphView のすゝめ / Introduction of GraphView
GraphView のすゝめ / Introduction of GraphView
 
基盤・設計まわりでしくじってしまった話
基盤・設計まわりでしくじってしまった話基盤・設計まわりでしくじってしまった話
基盤・設計まわりでしくじってしまった話
 
2020年版 Unity Package Manager 更新点まとめ
2020年版 Unity Package Manager 更新点まとめ2020年版 Unity Package Manager 更新点まとめ
2020年版 Unity Package Manager 更新点まとめ
 
Unity Development Infrastructure / Unity プロジェクトの開発基盤を大公開
Unity Development Infrastructure / Unity プロジェクトの開発基盤を大公開Unity Development Infrastructure / Unity プロジェクトの開発基盤を大公開
Unity Development Infrastructure / Unity プロジェクトの開発基盤を大公開
 
Future of UniFlow
Future of UniFlowFuture of UniFlow
Future of UniFlow
 
Clean Architecture for Unity
Clean Architecture for UnityClean Architecture for Unity
Clean Architecture for Unity
 
Visual Programming Framework for Unity - UniFlow のご紹介
Visual Programming Framework for Unity - UniFlow のご紹介Visual Programming Framework for Unity - UniFlow のご紹介
Visual Programming Framework for Unity - UniFlow のご紹介
 
Unity ユーザのための Git ハンズオン #2
Unity ユーザのための Git ハンズオン #2Unity ユーザのための Git ハンズオン #2
Unity ユーザのための Git ハンズオン #2
 
Unity で Unit な Test を書いてみた
Unity で Unit な Test を書いてみたUnity で Unit な Test を書いてみた
Unity で Unit な Test を書いてみた
 
AssetBundle (もどき) の作り方
AssetBundle (もどき) の作り方AssetBundle (もどき) の作り方
AssetBundle (もどき) の作り方
 
Unity meets Kinect -Unity で NUI を扱ってみた- / 2015.06.23 at TechBuzz Space
Unity meets Kinect -Unity で NUI を扱ってみた- / 2015.06.23 at TechBuzz SpaceUnity meets Kinect -Unity で NUI を扱ってみた- / 2015.06.23 at TechBuzz Space
Unity meets Kinect -Unity で NUI を扱ってみた- / 2015.06.23 at TechBuzz Space
 
Unity 5 の AssetBundle について (浅く) まとめてみた - 2015/05/22 第31回 Unity 勉強会
Unity 5 の AssetBundle について (浅く) まとめてみた - 2015/05/22 第31回 Unity 勉強会Unity 5 の AssetBundle について (浅く) まとめてみた - 2015/05/22 第31回 Unity 勉強会
Unity 5 の AssetBundle について (浅く) まとめてみた - 2015/05/22 第31回 Unity 勉強会
 
できる! Unity 2D (vol.2)
できる! Unity 2D (vol.2)できる! Unity 2D (vol.2)
できる! Unity 2D (vol.2)
 
20150216 Unity Hands-on 「できる!Unity 2D」
20150216 Unity Hands-on 「できる!Unity 2D」20150216 Unity Hands-on 「できる!Unity 2D」
20150216 Unity Hands-on 「できる!Unity 2D」
 
20150123 第28回 Unity 勉強会「Unity に於けるビルド自動化のおはなし & 設定管理とリソース管理のおはなし」
20150123 第28回 Unity 勉強会「Unity に於けるビルド自動化のおはなし & 設定管理とリソース管理のおはなし」20150123 第28回 Unity 勉強会「Unity に於けるビルド自動化のおはなし & 設定管理とリソース管理のおはなし」
20150123 第28回 Unity 勉強会「Unity に於けるビルド自動化のおはなし & 設定管理とリソース管理のおはなし」
 
20140926 NCMB勉強会 #4 - Unity meets SpriteStudio
20140926 NCMB勉強会 #4 - Unity meets SpriteStudio20140926 NCMB勉強会 #4 - Unity meets SpriteStudio
20140926 NCMB勉強会 #4 - Unity meets SpriteStudio
 
20140829 第24回 Unity 勉強会 - Unity meets SpriteStudio
20140829 第24回 Unity 勉強会 - Unity meets SpriteStudio20140829 第24回 Unity 勉強会 - Unity meets SpriteStudio
20140829 第24回 Unity 勉強会 - Unity meets SpriteStudio
 
20140822 Swift 勉強会 vol.3 - はぢめての Swift
20140822 Swift 勉強会 vol.3 - はぢめての Swift20140822 Swift 勉強会 vol.3 - はぢめての Swift
20140822 Swift 勉強会 vol.3 - はぢめての Swift
 
20140711 MySQL Casual Talks vol.6 / 続・Amazon RDS Casual Talks
20140711 MySQL Casual Talks vol.6 / 続・Amazon RDS Casual Talks20140711 MySQL Casual Talks vol.6 / 続・Amazon RDS Casual Talks
20140711 MySQL Casual Talks vol.6 / 続・Amazon RDS Casual Talks
 
20140618 教育・知育アプリのつくりかた
20140618 教育・知育アプリのつくりかた20140618 教育・知育アプリのつくりかた
20140618 教育・知育アプリのつくりかた
 

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

  • 1. Unity に於ける iOS ビルド自動化の おはなし【実践編】 2014.10.30 (Thu) / Unity 勉強会 vol.26 株式会社キッズスター システムデベロプメントチーム リーダー 森 哲哉
  • 5.
  • 8. おしながき • 自己紹介 • 前置き • やること • やりかた
  • 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 での申請の話
  • 20. Unity ⇒ Xcode このボタンを押すと…
  • 21. Unity ⇒ Xcode コレを雛形にして…
  • 22. Unity ⇒ Xcode こんなのが出力され…
  • 23. Unity ⇒ Xcode こいつにプロジェクト情報とかが定義される
  • 25. Pre Archive • アイコン設定 • ARC な Native Plugin へ -fobjc-arc の設定 • Other Linker Flags の設定 • 追加 Framework の設定 • アイコン下のアプリ名設定 • URLSchemes 設定
  • 27. Packaging × Xcode Project と Provisioning Profile が重要
  • 28. Packaging Xcode のメニューから [ Product ] > [ Archive ]
  • 29. Packaging Organizer で [ Export ] ボタン押して…
  • 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 オジサンとかに お願いすると、最高にオシャレ!!!
  • 61. まとめ • PostProcessBuild で、基本的な設定を置換 • Build → Archive → Deploy も自動化しよう!
  • 62. Thank you for your attention !