Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Unity に於ける iOS ビルド自動化のおはなし【実践編】
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Tetsuya Mori
PRO
October 30, 2014
Programming
280
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Unity に於ける iOS ビルド自動化のおはなし【実践編】
Tetsuya Mori
PRO
October 30, 2014
More Decks by Tetsuya Mori
See All by Tetsuya Mori
ビルドシステムを C# 大統一したお話
monry
PRO
2
1.5k
C# 大統一理論推進委員会 会員のための Unity Package Manager プロジェクト構成案
monry
PRO
0
1.8k
はじめての C# 大統一理論
monry
PRO
0
860
unity1week でチーム開発を成功させる秘訣
monry
PRO
0
330
Unity で ARゲームを作った話
monry
PRO
1
1.1k
Visual Programming Framework UniFlow のご紹介/Introducing UniFlow
monry
PRO
2
3.2k
UniFlow 完全に理解した / I can develop UniFlow a little.
monry
PRO
0
570
Democratized Unity Package Manager
monry
PRO
1
3.1k
使ってみよう! Unity RemoteSettings/Let's use Unity RemoteSettings
monry
PRO
1
1.3k
Other Decks in Programming
See All in Programming
AIエージェント時代のコードレビューを設計する
nogu66
6
2.6k
XP祭りでしか伝わらないフリップネタ #xpjug
murabayashi
0
140
Swift愛好会と私(ウホーイ) / Swift Fan Club and Uhooi
uhooi
0
150
標準パッケージに uuid が追加された 背景から見る Go らしい意思決定 / go_127_uuid_decision
convto
5
6.3k
20260828_品質と開発生産性を両立させる、AI時代のE2Eテストの考え方
magicpod
0
200
LLMは4年分のCompose移行を再現できるのか?実プロダクト279件のXMLで探る自動化の境界線
makun
0
590
App Intentsのビルドプロセスを支える技術
kntkymt
0
290
マイコン向けの軽量Ruby「PicoRuby」で各種デバイスを制御するネイティブアプリの実現手法
bash0c7
0
360
What We Talk About When We Talk About XP
m_seki
2
560
ハーネス設計入門 〜プロンプト、コンテキストの次〜
kinopeee
56
38k
Family mrubyの進捗
kishima
1
110
スマート反転とウェブアクセシビリティ
camiha
0
200
Featured
See All Featured
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
Writing Fast Ruby
sferik
630
63k
A brief & incomplete history of UX Design for the World Wide Web: 1989–2019
jct
2
500
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
350
brightonSEO & MeasureFest 2025 - Christian Goodrich - Winning strategies for Black Friday CRO & PPC
cargoodrich
3
830
Getting science done with accelerated Python computing platforms
jacobtomlinson
2
480
From π to Pie charts
rasagy
0
360
GitHub's CSS Performance
jonrohan
1033
470k
For a Future-Friendly Web
brad_frost
183
10k
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
120
120k
How to audit for AI Accessibility on your Front & Back End
davetheseo
0
530
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
370
Transcript
6OJUZʹԙ͚Δ J04ϏϧυࣗಈԽͷ ͓ͳ͠ʲ࣮ફฤʳ 5IV 6OJUZษڧձWPM גࣜձࣾΩοζελʔ γεςϜσϕϩϓϝϯτνʔϜϦʔμʔ ɹ࠸
͜ΜΜʂ
ʮ·͓ͨલ͔ʯ ͱ͔ݴΘͳ͍ɻ ΜΓ͌Ͱͬ͢ʂ
ࠓͷςʔϚ
None
ͱɺ͍͏Θ͚Ͱ Ϗϧυ ͷ͓ͳ͠Ͱ͢
͓͠ͳ͕͖
͓͠ͳ͕͖ w ࣗݾհ w લஔ͖ w Δ͜ͱ w Γ͔ͨ
ࣗݾհ
XIPBNJ w lɹ࠸zͱਃ͠·͢ɻ w BLBΜΓ͌5!NPOSZ'NPOSZ w ࡀˁ0ܕఱṝ࠲طࠗ w झຯʮ͓ञʯͱʮ߹এʯͰ͢ɻ
XIPBNJ w େֶΛ ࣗओతʹ ଔۀޙɺϕϯνϟʔΛసʑɻ w 8FCͷϑϩϯτΤϯυɺαʔόαΠυ͕ಘҙɻ w 6OJUZྺ͘Β͍ɻ w
"84ͱΩϟοΩϟϑϑ͢Δͷ͖Ͱ͢ɻ w ઈࢍ4IBEFSͷ͓ษڧதɻ
KPCT w lגࣜձࣾΩοζελʔzͬͯձࣾͰಇ͍ͯ·͢ɻ w ະबֶࣇʙখֶੜͷ͓ࢠ͞·Λ͓࣋ͪͷ ϑΝϛϦʔΛλʔήοτʹͨ͠ɺҭڭҭʹ ؔΘΔΞϓϦɾαʔϏεΛల։͓ͯ͠Γ·͢ɻ w ͓ӄ༷Ͱ&E5FDIͳҭʹԙ͍ͯ /PنͰల։͓ͯ͠Γ·͢ʂ
ࣾௐ͆
MTMBBQQT ͳΓ͖Γ ͬ͜͝ϥϯυ ύζϧςΠϧζ ͓͔͠ͷ͘ʹΛ ͭ͘Δͷ͡Ό ͳΓ͖Γ ΞΠεΫϦʔϜ ͞Μͬ͜͝ ͳΓ͖Γ
ϚϚͬ͜͝ ͓หΛͭ͘Ζ͏ʂ ͓͔͠ͷՈΛ ͭ͘Ζ͏ʂ ϋϯόʔΨʔ ͞Μͬ͜͝ ඈߦػΛ ΈཱͯΑ͏ʂ i18n i18n i18n i18n Ώ͔͍ͳ ͓Ֆ͞Μ App Store / Google Play カテゴリランキング1位 多数獲得!!!
લஔ͖
ڥ w 0QFSBUJPO4ZTUFN049:PTFNJUF w 6OJUZG 1SP0OMZ w 9DPEF XJUI$PNNJOE-JOF5PPMT
w 1MBUGPSNJ04 w -BOHVBHF$ w 0UIFS9DPEF&EJUPSGPS6OJUZ GPSLFECZNPOSZ
ࠓΔίτ w l#VJMEzϘλϯΛԡͨ͠Ҏ߱ͷ w ۃྗ9DPEFΛૢ࡞͠ͳ͍ͬͯ w 1PTU1SPDFTT#VJMEͳ
ࠓΒͳ͍͜ͱ w /BUJWF1MVHJOͷ w J5VOFT$POOFDUͰͷਃͷ
Δ͜ͱ
6OJUZ㱺9DPEF
6OJUZ㱺9DPEF ͜ͷϘλϯΛԡ͢ͱʜ
6OJUZ㱺9DPEF ίϨΛܗʹͯ͠ʜ
6OJUZ㱺9DPEF ͜Μͳͷ͕ग़ྗ͞Εʜ
6OJUZ㱺9DPEF ͍ͭ͜ʹϓϩδΣΫτใͱ͔͕ఆٛ͞ΕΔ
"SDIJWF
1SF"SDIJWF w ΞΠίϯઃఆ w "3$ͳ/BUJWF1MVHJOGPCKDBSDͷઃఆ w 0UIFS-JOLFS'MBHTͷઃఆ w Ճ'SBNFXPSLͷઃఆ w
ΞΠίϯԼͷΞϓϦ໊ઃఆ w 63-4DIFNFTઃఆ
1BDLBHJOH ίϨΛग़ྗ͢Δ
1BDLBHJOH 9DPEF1SPKFDUͱ1SPWJTJPOJOH1SPpMF͕ॏཁ º
1BDLBHJOH 9DPEFͷϝχϡʔ͔Β<1SPEVDU><"SDIJWF>
1BDLBHJOH 0SHBOJ[FSͰ<&YQPSU>Ϙλϯԡͯ͠ʜ
1BDLBHJOH ςελʔ͞ΜʹΔ༻ͷJQB࡞ͬͨΓͱ͔Ͷɻ
͜͜·Ͱͷ࡞ۀΛ ৬ਓ͕୮ਫ਼ࠐΊͯ ख࡞ۀͰɻ
@ dᵲᵲʏźŕũŽƀŕŜ
͡Ό͋ʜ
͍ͭࣗಈԽ͢Δͷʂʁ
ࠓͰ͠ΐʂ
Γ͔ͨ
&YQPSU9DPEF1SPKFDU
&YQPSU9DPEF1SPKFDU UnityEditor.BuildPipeline.BuildPlayer( string[] levels, string locationPathName, UnityEditor.BuildTarget target, UnityEditor.BuildOptions options
); ઌͣجຊ͔Β
&YQPSU9DPEF1SPKFDU BuildPipeline.BuildPlayer( new string[] { "Main.scene" }, "/Users/monry/SampleProject", BuildTarget.iPhone, BuildOptions.Development
| BuildOptions.AllowDebugging ); &YBNQMF ͜ΕͰ9DPEF1SPKFDU͕ग़ྗ͞ΕΔ
ίί͔Βઌ 1PTU1SPDFTT#VJME Ͱॲཧ͢Δ
"SDIJWF
"SDIJWF 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(); ઌͣYDPEFCVJMEίϚϯυ࣮ߦ 1SPWJTJPOJOHͷ*%J1IPOFߏϢʔςΟϦςΟ ͱ͔ͰௐΔײ͡Ͱɻ
"SDIJWF 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(); ଓ͍ͯYDSVOίϚϯυ࣮ߦ ϓϩδΣΫτ໊ɺ1MBZFS4FUUJOHTͷ 1SPEVDU/BNFΛࢦఆ͢Δ
ΞΠίϯઃఆ
ΞΠίϯઃఆ 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 ); J1IPOF1MVT༻ͷΞΠίϯ͕ൈ͚ΔͷͰɻ ࠷৽ ͰରԠࡁ͔ʁ ௐͯͳ͍ɻ
GPCKDBSDઃఆ
GPCKDBSDઃఆ 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"); } } 9DPEF&EJUPSGPS6OJUZΛ͏ 6OJUZ/PO"3$ͳͷͰɺ"3$ͳ/BUJWF 1MVHJOʹϑϥάΛ͚ͯ͋͛Δඞཁ͕͋Δɻ
0UIFS-JOLFS'MBHTઃఆ
0UIFS-JOLFS'MBHTઃఆ XCProject project = new UnityEditor.XCodeEditor.XCProject("/path/to/export"); string[] flagNameList = new
string[] { "-ObjC", "- all_load", ... }; foreach (string flagName in flagNameList) { project.AddOtherLDFlags(flagName); } ಉ͘͡9DPEF&EJUPSGPS6OJUZ͏ ֎෦4%,ͱ͔͏ͱ͖ʹඞཁͩͬͨΓ͢Δɻ
Ճ'SBNFXPSLͷઃఆ
Ճ'SBNFXPSLͷઃఆ XCProject project = new UnityEditor.XCodeEditor.XCProject("/path/to/export"); project.ApplyMod(Path.Combine(Application.dataPath, "path/to/projmods")); ͬͺΓ9DPEF&EJUPSGPS6OJUZ͏ QSPKNPETͳΔϑΝΠϧΛ৯ΘͤΔ
Ճ'SBNFXPSLͷઃఆ { "group": "", "patches": [], "libs": [], "librarysearchpaths": [],
"frameworksearchpaths": [], "frameworks": [ "Security.framework", "CoreData.framework", ], "headerpaths": [], "files": [], "folders": [], "excludes": ["^.*\\.meta$", "^.*\\.mdown^", "^.*\\.pdf$"] } IPHFQSPKNPETͷαϯϓϧ +40/ܗࣜͰهड़ɻ ঢ়گʹԠͯ͡ଞͷΩʔઃఆͨ͠Γͱ͔ɻ
ΞΠίϯԼͷΞϓϦ໊
ΞΠίϯԼͷΞϓϦ໊ // Unity-iPhone/en.lproj/InfoPlist.strings CFBundleDisplayName = "HogeFuga"; // Unity-iPhone/ja.lproj/InfoPlist.strings CFBundleDisplayName =
"ほげふが"; ઌͣ*OGP1MJTUTUSJOHTΛ࡞Δ ϑΝΠϧ໊ͱ͔ίϨ͡Όແͯ͘0,
ΞΠίϯԼͷΞϓϦ໊ 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) ); } *OGP1MJTUTUSJOHTΛ7BSJBOU(SPVQʹՃ 7BSJBOU(SPVQରԠ൛͕ίνϥʹ͍͟͝·͢ɻ ,OPXO3FHJPOΛՃ͠ͳ͍ͱμϝɻ
63-4DIFNFTઃఆ
63-4DIFNFTઃఆ 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); JOGPQMJTU 9.- ΛΰϦΰϦॻ͖͑Δ จࣈͷτίɺॻ͖͑ͯͶɻ
͓·͚
͓·͚ w Ϗϧυͨ͠JQBΛ%FQMPZ(BUFʹࣗಈ164) ͢ΔͱɺΦγϟϨʂ w ߋʹͦͷ݁ՌΛ$IBU8PSLͳΓ4MBDLͳΓʹ ࣗಈ1045͢ΔͱɺͬͱΦγϟϨʂʂ w ߋʹߋʹɺίί·ͰΛ+FOLJOTΦδαϯͱ͔ʹ ͓ئ͍͢Δͱɺ࠷ߴʹΦγϟϨʂʂʂ
·ͱΊ
·ͱΊ w 1PTU1SPDFTT#VJMEͰɺجຊతͳઃఆΛஔ w #VJMEˠ"SDIJWFˠ%FQMPZࣗಈԽ͠Α͏ʂ
5IBOLZPVGPS ZPVSBUUFOUJPO