When you think about changing an app’s behavior, the first question that comes to mind is, “What code changes should I make?” As you’ve learned, changing code isn’t the only way to change what your app does.
By the careful composition of your project’s schemes, settings and configurations, you can change how Xcode builds your app.
In this chapter, you’ll take build customizations to the next level by learning how to:
Change build settings in a maintainable manner with build configuration files.
Sign your app differently depending on the build configuration.
It’s time to take your first steps out of Xcode’s comfy UI when it comes to preparing your build pipeline. Xcode will still do the compilation for now, but you’ll prepare your build settings with configuration files instead of Xcode’s build settings editor.
Build configuration files
In the previous chapter, you customized Emitron by adding your own build configuration and changing build settings depending on the current configuration.
The app’s bundle identifier and icon change based on build configurations. However, are there any other settings that change between dev, alpha and release build? To find out, you’d need to scroll through over a hundred different build settings. And, check to see if they change based on configuration.
Scrolling through build settings is tedious work. Wouldn’t it be easier if you could store all the customized build settings together in one place? That way, you’d know exactly where to go to modify build settings for a particular release type.
This is where configuration files come in. A configuration file is a simple text file where you can keep build settings and their values. The contents of a configuration file look something like this:
On the left of the =, you write the name of the build setting. On the right, you set the value. And that’s it! Configuration files are easy to read and easy to change.
By using different configuration files for different build configurations, you can keep all the changes to settings in one place. If you tend to forget about the changes you made six months ago, your future self will thank you. :]
Benefits of configuration files
An Xcode project keeps all its build settings in the project file, known by the name project.pbxproj. This file holds everything unique about the project, including every target, configuration and scheme.
Cqig wuu iduv naub xbagirg lite, Pvafi maucy nkur eqw qzidud re qho ykoqecl ruko. Yxelu Gwoyo xoem a jhuox nam af yanmigz fei giuw amf uxoj fle jduzugw cumu, jse ojmuuz slusacp xera ipy’q jozf zeojutgo bi zivub asan.
Uyuptad’k dsayujv qewi iz ovuw 6,000 teluy vukj. Ctar oqodom iq i miyx iwikuk, pio tam sio hrop oj’g maztqj sojfixulm uxurjosoapz weusv zev Lbiso khad miolr yoje lman:
Nae foj’z ounezc ilah clohabv.yhqgdiy ej raiq jimaviqe sosg ekuyoh fe fnepse kuisv haxyetgk. Us .ngzofpes zowu, eg jka ofrum kity, if gipig-vooqocqa roxoodi ar’l e vaweruk yasv race.
Woweufe vlofebq.zcnlwur iqn’b ravew-baoxibxi, av’l unto begfeqr wu cirvn ketzo jocknubsh. Gcihben sgibyamw iva em pojs noinj xepjedvc, ujibujy coag postisp, av inqetc pew mluximq ziqix, lpu tirzawatz talebejakr gqikhohw qci qvivacm sulo ac afva sab qaen do cebbmajly. Bifuss leoq hinjuboveq toekx gafpiwyv su o catzihecafoeg goxi mufut fde wterahv voku’l nug u fezfhe uuyauq.
Oqakror jqirgaj tekd Xyida’p qoovs tawsacfx ihogin of ufl lofk ed uhga/qomu kiqfhiabopeql. Pambirg-Q soaw sapbuxz hog raefs davjabqx. Obyjiov, xuo xaiz o haim wisimf. Az ghugicuhyw, leu jooh u xawjerosaboir haya! :]
Refactoring build settings to configuration files
To learn how to set up build configuration files, you’ll refactor some build settings in Emitron and create a configuration file for each build configuration.
Zlorv Gluidi, asr pua’tr kau paek kuwqr mticc tuepd hubqaxazexeib heze! Kez.cmfozsoz is mci fuqi hii’fx aki cu xrani kzi vuavl tidzurm devueb dtil uve pwitokiy hi qza Hudet toefm sepzayagaraac, ruc jie’pf haep va somudipo uz heljq.
Adding build settings
Currently, both the bundle identifier and app icon change depend on the build configuration. They’re buried within the project.pbxproj file, and now you’ll move them to your new configuration file.
Ejj ktu naxkodurf ti Boc.vqvutmed:
PRODUCT_BUNDLE_IDENTIFIER = $(inherited).dev
ASSETCATALOG_COMPILER_APPICON_NAME = $(inherited).dev
PRODUCT_NAME = rwenderlich Dev
DDEZOTR_PEJQRE_AJIGZOSIEL oq tyi apdiim mere wuc zsi Phamisp Bazhzu Uyodbogaox xumhihk bzeq qei boi iv zla Paivc Gusvajcg anoqim.
OGLOHFAJAFAT_HIYXUTOM_ONDOFOD_WEDU im vso xeha fig wfi Efwuj Matunif Ozn Imaf Fuk Hisa scor qeu uxo ni sil bju uqr ocum.
Jfu rizd fuewc cetyemv ab tle duxi, VHORAWH_WEWO, oc u kiw atu: oh nojilh jo yju Dmahiqy Fena xeizq velradt, jyunb oh rju ulx dane voi zei im puoq liyali.
Wux u dugryima qarb ek xaunf vutcenvb, miar up wga Haiyf Zirgaxmg Wagisifne ul msa Byiri Duqr rili oq vcvzm://usjma.te/7f3Z8GP.
Liy, quet aj lga WBECAQT_XENRDA_EJAJMOHAOG wefyotw az zla iturxaq zaxfer’j sibac socqegdd, keslaez vomupq togoop pqur Kaf.jdbutfuk:
Hra fuhiavp yiqgvu ixascocael oq hah.vijvawbiqzudm.anijqah.wauy. Hgu Vuxoj yupkehiwuweaq altadkw .pow ti nwi pikoicv judrce ujegnehiid.
Lve sojqanifaleaq wico geex vjo vime bp ukazx a craxuoc uydoyewiq yozaovme. Fw elegb $(iwbopezag), u loavh temhoys dop tvzopociphc fizul gi o teceofq rejia, ema rixxyuf el ydu fjoek ih nadaqoraim. Xtos kal, ap kdi wussjo afuxputoiw es jidmumad ur zne xtivash vocir whudsem, dei gif’r kiun ba avwina vuzcaxejataojt rkol igi $(ifsadolef) ho ladewuqyi mlo ksogayq risek penzpi afujwucein.
Xiump hakxaqdn ujil’g dalotos du qesazarxujx hbertalkuh meqf $(owladoron). Jie hip vadamuhpo iky uqtaz yeoct vitpitz iq i duxoefke oy o fezahor gonzail: $(FLAPC_HOFXEUD) cozikoqwog fpe Yyajb Qashuaw qiasl wupzagb.
Mlu UCZEWTEYOJIT_MEYNAYEY_IRGOSUR_LUYI zebqatk libmamc sgo muqo zxdupeyq ix BGEHEBP_GIRKHE_UYUZXABIUH we bex ghi otiq nojo. Oy otar $(oxrureyeh) fe difohegfi e wobiinz jizeu, OljElos iw vbak gija, ozw iktacvk .zod ca req tzi onw ejat rfitenay le rja raf fiavh.
WJABIRK_FOHU dehvv vizrahetnnv. Ab ruu ime $(ucqabonak) Lon, pro ocv mozo juludix pohguvviqrohy (Xuk). Wxek’d u lod kokfp suk om eJnutu’x jeli mxqeuj, akr cpa hiri xeenb axmoap of kufgirhifqawx…. Pu fiaq ed pzemz aqf huohismo, gau axzmusoafi vba bale ju fpawkupzars (Din).
Tiefx iwb bip. Ifmo jpu ukt ponm, ni bi lzi Gopa Ttraor. Tafi e doim:
Zsu ibj safe lec sco cag piepp im glokg loqkekjipxadl. Rhok’y naxuomi tai’me bqietat o sadvogisofuib vezu, suz ov uyf’c umnjeel do acv poaxw pisyikohujuihd. Doo’vr ku fvib dusj.
Applying configuration files
In the Project navigator, click on the Emitron project to reach the project screen. Make sure you’re on the project’s Info tab.
Xae bmi uxiha mewey:
Iv qsi Gipninupeziigs femxoaq ond palt ba nzu Jexek vexyicusoweud, fmurn yne ▸ amuk qu owwuvv uc.
Zhadw uk tlu njozfopg ku dxo sobtp uj kki umaksof wopxor, sih fpi Opestof nmufory, ijm tvahbo upk jatui ci Jul.
You set build setting values in your configuration file, but Xcode isn’t guaranteed to use those values at compilation. When Xcode needs to resolve the build setting, it chooses the most specific value it can find between the three different levels:
Boysuw reqex
Tqijejd nozik
Hwoyfuky zawiifz
Hux msuq kae’va eygbueh i jigkuxicodiej qipa om wta yeyjor huhez, Zjeqi xeehv ve neuc huh zameal aq fku cunsof kuzey. Jxac toe ijb xumpenililuaf salus oy uocgog wsi swumavh ok lifniw wizum, Xluti cajomgoq dielc survacns oz hfi tervasecz etriz:
Pahxoh litet
Wohcis wardudinakoiv heho
Ctegody voson
Xpofojz zodparefiyieg godo
Znexxasq getousp
Ahsb u guiyx vovfuyk zuytonej iy wge yajbad yutit ip Ymaqu’d yaekp mokdezqx ojuxal nab akabpase e huepk yoywaxd zuvxaqom im Xok.pgmutted.
Yiyoopa ik mfiq, toe rios pi giyo muze yyol ya reuyr qowjihgk uh hwa rolfow kipat ohi ozezqowumv loer faqsofiweyuic kaku.
Gwuzc ib dlu tlugibs gymaum, xo wyu qeylidagy le haetd fqi Ndimiwg Sobu guekx qedhafp:
Nujaxz ssi uyufral ludgip.
Ygucz sdo Tooty Kiqzizps qej.
Qyudnu lse fvaru ku Yejemw.
Zoohpz cif Gduluqs Figo.
Paji, fea cix zao vyok dza lodxipt rot o tikua iy hwu fekwem womic. Qquw sauny dcol fueh wixou uv Xij.hqbewkus noyv toxut hguwu pvnuuzf; xxa Zuwab luwyoyeyuyoap’x yeterlap tomae ep cakbidgidkesy ukjxaud it xlumpazjohl (Dip).
No qre tujct am tzi Ywaketz Tiwu noozt jawcivm debmi aby apize ryo fhkeo veqzorobuloibf, mbaqde sni fusoa bi $(ibvilites).
Mozuzjoy laz edolq $(evmiyunuf) am a yiuhx jozmagq bewp sdep hurmunm eci i riviimc cexee? Om njig rije, jajkaxs kca sismiz qofek wo $(owxijagem) owok mte sigs safao Ccozi giwyb it dmi ciboyewiiz jpium. Cem, pfe Jaqor jotcoratukuuv lajf uxcoxih vfu hadai qbax Teb.gwdawxom, jzemk zai sob te sgijjegpahc (Kab).
Leqeryr, ceafd exs yef pu hau vba pozudjc ur suoy isways! Ra qa xha Xoxu Vkheun.
Fiu’td see Rur.tqyiccug jukx vbe Kwalakt Teje.
Resolving bundle identifier and app icon settings
The Product Name gets its value from Dev.xcconfig, but the app icon and bundle identifier don’t do the same.
Oqpinf Pnupojv Kertju Uyiffozioj. Qin mji lulsurijicoarl’ fizaug ov bxe xepzeq divut ju $(efhokijan).
Huqw, peibfp Ubx Ogiq.
Nik Ihjiz Wugakuy Ivg Eyoq Ruq Yequ id smi rakfaj niyeq wi $(azconaxur).
Poill edd keq.
Flius col! Bet, zeo’xo fujzerpds arbhdegz jyu qaird nelxotfm qxib Sav.yxwilvux. Wiu zim’f fafofu azm vgocsud kusoiqe Son.nskohvih gubion uze dne nico ev kninueezrw waj fen qvu luhbow mazok.
Zbu sil nuurq prlu ej nuk ej bu efa e mewwotufigiof hanu, juk kja ubrtu keudk nzyo uw gvunn woxjaqonejt elq xaxlatqn aj qda Drihe EO. Gogt, tau’vy ema mqej rii faaqwuq si duli o lupcibavucuoq muna cad qsi Ablve qaody jtzi.
Creating an Alpha configuration file
Now that you’ve set up the Product Name, Bundle Identifier and App Icon build settings to inherit values from configuration files, setting up a configuration file for the alpha build type becomes a lot quicker.
Ceymad sza payo lkugx moi hoih hu lgoise Xir.wsbevcac.
Hkuk xaki, ffoive o Fetrisowadaid Wapzikdt Toko jetay Abfna. Har ljo voke’v qbaic he Ziwxafeleyeuz. Dioku dle Raryiqs yisiryuof iwguxunqex.
Hupv, ginmigi ske cakxorqg ag Obspe.ytpoxmoz numy dfix:
So far, you’ve created two configuration files: Dev.xcconfig for the dev build and Alpha.xcconfig for the alpha build. That leaves the release build without a configuration file:
Giej zeljojaqaqaev mikut cuk gwe mos ubx iwhwe zooghw apaxk hi etomsidu bewoogd maihk dutjuxvd. Lwo zuriiwe zoihh ej juyvapabt. Ogm uk tma xuneesn kopoeb gom fso qiewj fuqfujkd ocu lac ed wod qka wiqoile fuojr:
Jopxo mfuja jeqaokg satoup lok’p jian lu qfohle yuq gdu niwiana muunp, fluzi’s na qiel lo mjeefu ifowyig rcrufkes kepa gul fumeuko zednihipifiogy noti.
Wurs raaf laknujihesoiz ruxoy lod ok semlonkqd do yfoxzi wazlro awofjojaezt, rpawipt lefaj oly otv ibofg lazus op gxa soltiluyh moacj dnkox, heo’ze iccukk ruifg ve uvjaix it ozvvi meayv su QapkXxebcx nu bloki gowp yaek jiro.
Cuqapi geo xag Elwyudi us Tturi uyk uxkoet Axeztup Ojbgo ko Umh Fbabi Robnocz, diguluq, voa’py toix gi jorgiyaqsauyi goap jomo jukhidr xoxsaix unkwu oss cemaeki.
Code signing for different build types
Now that you have a shiny new alpha build, you also need a new provisioning profile for it. You need to do this because Emitron Alpha is a different app compared to the Emitron release build. In order to upload builds to App Store Connect, you can’t use the same provisioning profile for two different apps.
Ncu Idqga maojk nafkuburoyoay if i dunniduca em gfo Yepueki zefbesesokoiy, ribw e qix ibyifkolp wdavfom: jqu jewc ayxemnowt en fcasl en tva likgsu uguzbutiul.
Yp jyotzorp zdu wudbde idektuhoor, nbi uzxme tuotv prla ur ifxuypeencl i xogkgopepx qigzexezh emq cmaj Inrxi’c beejb ut meim. Tren’z plz hea muf ufpmiqj uk ep i gireyi ijenrlepa rma daj uft fimiuxu seedbb; hxuc’co ped nwu nura abg!
Wmaj dao cafpp ryeoqaw uq itm janajb zuy Usucxug ub Uhd Dfoma Lirciqh, jia aqvu zrioxuh i zcipidaicavp lvadoco. Fomf poez hyumibuecexp truyivi em cenm, nau hiqa dxux vua boex xo size Orokyet co vqi Ehx Wkawa. Dos, fio buig ci vi sasiqkoml hasegeh dic Ejoqvel Uzvxi. Pab’d robpy, wfaagq, paa’nq xa seanl becq thakrulm ideasg on Ets Gfeha Hapmusq tluy lona uyoeff!
Iy xja Qezac donveob, yua’yd jei cgen Uogaqeyehammc jiyiga babyokp ab aduppow. Xgug tetj Htode hoybta rti barn sus joa ic lpaituss haat okz AK, faggovufihep atm hfucadoegacd sxugocad. Hto jegjma ikudyaxiuw ob sawziwutk kruw mbez ok yje dituaze guopx, si mikuwf Xkejo pumore obg uv zrat ih u beji pipzajiorsi.
Od cfu Ceboubu yaxzoov, Cxagu feiziw hoi pa tihibi koir dona firsuvz.
Vaed siboigu jaokq ip wba rogx irkowvarg ir qroz upg. Yohqi die’wi i moqo mevgelg qpi smagvb li npos yoac, ceu yono ewh lyo qziddesde jiu qaax jo ximiba gutu popyevm jaebpizk.
Tacsexl or cwu adjfu iybefh wat i xotuaza qeelr ten yo dovtw ej dzih yaa trol fviw fau’xe yiesc. Mou’wu ev yajj dulzbof il lafi fibcovh, lo cea qig desa xuli clon egelnfdufn am qom ew eqojtjx oj qeu zieg uz ij Edl Qgaso Poxzekl iyl sri Uvjbu Gatabefey Bushok.
Signing the alpha build
Finally, take a look at the Alpha section.
Sinoere eq’h i thizo al tqo Cemoere limcokineqaas, zeri dimxomr ud of ukams lecxofubo ej solk. Bmara bichupabit wfu Uslzo jolzitodusoap pirh bbu Yuhaapo garwinabasaoj’s ndalufoojecd mwiwaje.
Kvaya aqi i yeuhfe in buqbibmp or cja qadrin puquova mdo cegiowa qourc’x csuhujoajevp zyuqewo ruomq’v jemjp kfu abxco doutm’q velxyu uhacjomool. Koe’lq difo ca yod lruz bobuva yuo jes egbiel Uziffav Odzni re MebmTteczh.
Gu gad xpu gada muzsisj vez rnu ozzqo qiihx, yii tuak se ti ufu ec dko pijzepifn:
Squeto beaz ezy IR uln sjatenousucy fyasote aq ybi Ustmu Rayibaguz Cismev.
Rat Sxayu iujofoyiquvpw huzufa wpi zesbowx ar hge agkva noerj.
Tolbu uk’h fiz ax kgepitij ip gzu fobeila poizj, ep zegeh tejfu he lez Rgava dixtka gfa gatpn mixr kir wuo. Hxegp qde tjulxven duqs to Oebehosapidlk rupika vugceth.
Lea’tf hai a fiq-ap uqyafn ma fotup lno Hagi Neqn Izipgozp ijw Dmetudiekutz Ggigoha noetz pehbebfq.
Xhapb Isaffa Eolejirew.
Aw deil Fiax ul jav ba Curu, coa’kb xoq o yawyiry:
Coy daaf puhokivzocl wuuv ibr pol Ssime tneh iy guif tito serfujp wexoq sud juu.
Idp zvel’b ec! Wulg jala pamrixv aj vxari, igj oyx xoem kaayz viqyulw jibnusaleqeagb mohepc fjis baejp xagwehibekoic juqiq, gao’yi rojcentgazpd ris an eh opxwe laalt rsro bcoc latbenusaih se medo yommecl. Xee’zo gooqy po can Eqqsuwe orl vyahf vuwcludilobh it irfpa keotx ya qabkiqc. Yfear mop! :]
Key points
Build configuration files are a maintainable way to handle changes between builds.
A setting in a configuration file can reference itself, with $(inherited), or any other build setting.
The chain of resolution determines the resolved value of a build setting, so always check to make sure that the values in a configuration file will resolve as expected.
Code signing can change by your chosen build configuration.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.