iOS 多個(gè)環(huán)境一次打包

概述

偶然看到一個(gè)很有趣的問(wèn)題:如何在ios環(huán)境下實(shí)現(xiàn)多個(gè)環(huán)境同時(shí)打包。

談到多環(huán)境,我想大多公司都至少有2-3個(gè)環(huán)境,比如Test環(huán)境,UAT(User Acceptance Test)用戶驗(yàn)收測(cè)試環(huán)境勒庄,Release環(huán)境等等串前。當(dāng)需要開(kāi)發(fā)打多個(gè)包的時(shí)候,一般常見(jiàn)做法就是直接代碼里面修改環(huán)境變量实蔽,改完之后Archive一下就打包了荡碾。或者在App中內(nèi)置一個(gè)切換的按鈕局装,實(shí)現(xiàn)環(huán)境的切換坛吁。

或者,你們公司已經(jīng)搭建了Jenkins環(huán)境铐尚,利用Jenkins環(huán)境就可以給app來(lái)配置一下多個(gè)環(huán)境變量拨脉,之后Jenkins分別再不同環(huán)境下自動(dòng)集成即可。

那么如何實(shí)現(xiàn)ios的多環(huán)境打包呢宣增?參照網(wǎng)上的一些方案這里做一個(gè)簡(jiǎn)單的總結(jié)玫膀。要實(shí)現(xiàn)多環(huán)境打包,現(xiàn)在主流的方案有三種(各有優(yōu)劣)爹脾。

1.利用Build Configuration來(lái)配置多環(huán)境

2.利用xcconfig文件來(lái)配置多環(huán)境

3.利用Targets來(lái)配置多環(huán)境

一帖旨、Build Configuration方式

做過(guò)ios開(kāi)發(fā)的人都知道Build Configuration,系統(tǒng)默認(rèn)提供2個(gè)環(huán)境灵妨,一個(gè)Debug解阅,一個(gè)Release。這里泌霍,我們利用的就是Build Configuration給我們提供的配置功能來(lái)實(shí)現(xiàn)多環(huán)境打包瓮钥。具體步驟如下:

1,新建Build Configuration

點(diǎn)擊Project里面找到Configuration烹吵,然后選擇添加一個(gè)Configuration碉熄,系統(tǒng)默認(rèn)是2個(gè),一個(gè)Debug肋拔,一個(gè)Release锈津。這里我們需要選擇是復(fù)制一個(gè)Debug還是Release。Release是不能調(diào)試程序凉蜂,因?yàn)槟J(rèn)是屏蔽了可調(diào)試的一些參數(shù)琼梆。


20170717103707845.jpeg

這里我們新增一套環(huán)境:Configuration。在這一套包含了一些編譯參數(shù)的配置集合窿吩。如果此時(shí)項(xiàng)目里面有cocopods的話茎杂,打開(kāi)Configuration Set就會(huì)發(fā)現(xiàn)是如下的樣子。


20170717104056461.jpeg

然后打開(kāi)項(xiàng)目的pod文件纫雁,打開(kāi)配置是會(huì)看到如下信息:
20170717104217603.jpeg

說(shuō)明:pod安裝完成之后會(huì)自動(dòng)生成xcconfig文件煌往,如果你手動(dòng)新建這個(gè)xcconfig,然后把原來(lái)的debug和release對(duì)應(yīng)的pod xcconfig文件內(nèi)容復(fù)制進(jìn)來(lái)轧邪,這樣做是無(wú)效的刽脖,需要pod自己去生成xcconfig文件才能被識(shí)別到羞海。

新建完Build Configuration,這個(gè)時(shí)候需要新建pod里面對(duì)應(yīng)的Build Configuration曲管,要不然一會(huì)編譯會(huì)報(bào)錯(cuò)却邓。如果沒(méi)用pod,可以忽略一下這一段院水。


20170717104400404.jpeg
2腊徙,新建Scheme

20170717104508168.jpeg

新建完成之后,我們就可以編輯剛剛新建的Scheme檬某,我們可以把Run模式和Archive都改成新建Scheme撬腾。
20170717104623591.jpeg

注意:如果是使用了Git這些協(xié)同工具的同學(xué)這里還需要把剛剛新建的Scheme共享出去,否則其他人看不到這個(gè)Scheme橙喘。
20170717104714778.jpeg

3,新建User-defined Build Settings

回到Project的Build Settings里面來(lái)胶逢,Add User-Defined Setting厅瞎。

20170717105115264.jpeg

CustomAppBundleld是為了之后打包可以分開(kāi)打成多個(gè)包,這里需要3個(gè)不同的Id初坠,建議是直接在原來(lái)的Bundleld加上Scheme的名字即可和簸。CustomProductName為app顯示在手機(jī)上的名字,建議直接按環(huán)境給予描述碟刺,例如:測(cè)試(debug)锁保,線上(relase),UAT等半沽。
20170717105322581.jpeg

需要注意的是:Pods的Build_DIR這些目錄其實(shí)是Pods自己生成好的爽柒,之前執(zhí)行過(guò)Pod install 之后,這里默認(rèn)都是配置好的者填,不需要再改動(dòng)了浩村。

4,修改info.plist文件 和 Images.xcassets

打開(kāi)info.plist文件占哟。由于我們新添加了2個(gè)CustomAppBundleld 和 CustomProductName心墅,這里我們需要把info.plist里面的Bundle display name修改成我們自定義的這個(gè)字典。編譯過(guò)程中榨乎,編譯器會(huì)根據(jù)我們?cè)O(shè)置好的Scheme去自己選擇Debug怎燥,Release,TestRelease分別對(duì)應(yīng)的ProductName蜜暑。




為了方便區(qū)分不同的環(huán)境铐姚,你還可以對(duì)不同環(huán)境下App Icon,名字等做一個(gè)修改肛捍。

既然我們已經(jīng)新建了這幾個(gè)scheme谦屑,那接下來(lái)怎么把他們都打包成app呢驳糯?

這里分享下實(shí)際打包過(guò)程中的一些經(jīng)驗(yàn)。

每個(gè)環(huán)境都要設(shè)置好Debug 和 ReleaseG獬取T褪唷!

千萬(wàn)別認(rèn)為線上的版本只設(shè)置Release就好悍手,哪天需要調(diào)試線上版本帘睦,沒(méi)有設(shè)置Debug就無(wú)從下手了。也千萬(wàn)別認(rèn)為測(cè)試環(huán)境的版本只要設(shè)置Debug就好坦康,萬(wàn)一哪天要發(fā)布一個(gè)測(cè)試環(huán)境需要發(fā)Release包竣付,那又無(wú)從下手了。我的建議就是每個(gè)環(huán)境都配置Debug 和 Release滞欠。

在打包的時(shí)候古胆,一定要注意將Scheme的名字和編譯方式區(qū)分開(kāi)。選擇一個(gè)Scheme筛璧,只是相當(dāng)于選擇了一個(gè)環(huán)境逸绎,并不是代表這Debug還是Release。


20170717110144760.jpeg

配置好上述之后夭谤,就可以選擇不同環(huán)境運(yùn)行app了棺牧。可以在手機(jī)上生成不同的環(huán)境的app朗儒,可以同時(shí)安裝颊乘。


20170717110324703.jpeg

接下來(lái)說(shuō)幾種動(dòng)態(tài)配置環(huán)境變量的方法。
動(dòng)態(tài)配置環(huán)境變量

使用GCC預(yù)編譯頭參數(shù)GCC_PREPROCESSOR_DEFINITIONS
進(jìn)入到Build Settings里面醉锄,可以找到Apple LLVM Preprocessing乏悄,找到Preprocessor Macros,在這里我們是可以加一些環(huán)境變量的宏定義來(lái)標(biāo)識(shí)符恳不。Preprocessor Macros可以根據(jù)不同的環(huán)境預(yù)先制定不同定義的宏纲爸。

20170717110621421.jpeg

使用plist文件動(dòng)態(tài)配置環(huán)境變量

首先,新建3個(gè)名字一樣的plist作為3個(gè)環(huán)境的配置文件(新建三個(gè)配置文件妆够,分別放在3個(gè)不同文件夾下面即可)识啦。


20170717110945047.jpeg

接下來(lái)我們要做的是在編譯的時(shí)候(運(yùn)行app前),動(dòng)態(tài)的copy Configuration.plist到app里面神妹,這里需要設(shè)置一個(gè)copy腳本颓哮。


20170717111122742.jpeg

進(jìn)入到我們的Target里面,找到Build Phases鸵荠,我們新建一個(gè)New Copy Files Phase冕茅,并且重命名為Copy Configuration Files。其中,腳本能保證我們的Configuration.plist 文件可以在編譯的時(shí)候姨伤,選擇其中一個(gè)打包進(jìn)入app哨坪。再通過(guò)讀取這個(gè)plist里面的信息就可以做到動(dòng)態(tài)化。
使用單例來(lái)處理環(huán)境切換

當(dāng)然使用一個(gè)單例也可以做到環(huán)境切換乍楚。新建一個(gè)單例当编,然后可以在設(shè)置菜單里面加入一個(gè)列表,里面列出所有的環(huán)境徒溪,然后用戶選擇以后忿偷,單例就初始化用戶所選的環(huán)境。

二臊泌、利用xcconfig文件配置多環(huán)境

提到xcconfig鲤桥,就要先說(shuō)說(shuō)幾個(gè)概念。Xcode Workspace渠概、Xcode Scheme茶凳、Xcode Project、Xcode Target播揪、Build Settings 贮喧。

Xcode Project

project就是一個(gè)個(gè)的倉(cāng)庫(kù),里面會(huì)包含屬于這個(gè)項(xiàng)目的所有文件剪芍,資源塞淹,以及生成一個(gè)或者多個(gè)軟件產(chǎn)品的信息窟蓝。每一個(gè)project會(huì)包含一個(gè)或者多個(gè) targets罪裹,而每一個(gè) target 告訴我們?nèi)绾紊a(chǎn) products。project 會(huì)為所有 targets 定義了默認(rèn)的 build settings运挫,每一個(gè) target 也能自定義自己的 build settings状共,且 target 的 build settings 會(huì)重寫 project 的 build settings。

Xcode Project 文件會(huì)包含以下信息谁帕,對(duì)資源文件的引用(源碼.h和.m文件峡继,frame,資源文件plist匈挖,bundle文件等碾牌,圖片文件image.xcassets還有Interface Builder(nib),storyboard文件)儡循、文件結(jié)構(gòu)導(dǎo)航中用來(lái)組織源文件的組舶吗、Project-level build configurations(Debug\Release)、Targets择膝、可執(zhí)行環(huán)境誓琼,該環(huán)境用于調(diào)試或者測(cè)試程序。

Xcode Target

target 會(huì)有且唯一生成一個(gè) product, 它將構(gòu)建該 product 所需的文件和處理這些文件所需的指令集整合進(jìn) build system 中。Projects 會(huì)包含一個(gè)或者多個(gè) targets,每一個(gè) target 將會(huì)產(chǎn)出一個(gè) product腹侣。需要注意的是叔收, Project 可以包含多個(gè) target, 但是在同一時(shí)刻,只會(huì)有一個(gè) target 生效傲隶,可用 Xcode 的 scheme 來(lái)指定是哪一個(gè) target 生效饺律。

Build Settings

build setting 中包含了 product 生成過(guò)程中所需的參數(shù)信息。project的build settings會(huì)對(duì)于整個(gè)project 中的所有targets生效伦籍,而target的build settings是重寫了Project的build settings蓝晒,重寫的配置以target為準(zhǔn)。

一個(gè) build configaration 指定了一套 build settings 用于生成某一 target 的 product帖鸦,例如Debug和Release就屬于build configaration芝薇。

Xcode Scheme

一個(gè)Scheme就包含了一套targets(這些targets之間可能有依賴關(guān)系),一個(gè)configuration作儿,一套待執(zhí)行的tests洛二。

xcconfig使用

1,新建一個(gè)xcconfig文件,然后在project設(shè)置一下攻锰。



20170717121203902.jpeg

接下來(lái)晾嘶,把配置文件換成我們剛剛新建的文件。細(xì)心的讀者可能發(fā)現(xiàn)娶吞,其實(shí)我們一直使用的cocopods就是用這個(gè)文件來(lái)配置編譯參數(shù)的垒迂。

GCC_PREPROCESSOR_DEFINITIONS 是 GCC 預(yù)編譯頭參數(shù),通常我們可以在 Project 文件下的 Build Settings 對(duì)預(yù)編譯宏定義進(jìn)行默認(rèn)賦值妒蛇。

在Build Settings里面的 Apple LLVM 7.X - Preprocessing - Preprocessor Macros 机断。


20170717121647562.jpeg

Preprocessor Macros 其實(shí)是按照 Configuration 選項(xiàng)進(jìn)行默認(rèn)配置的, 它是可以根據(jù)不同的環(huán)境預(yù)先制定不同定義的宏,或者為不同環(huán)境下的相同變量定義不同的值绣夺。

在xcconfig 我們可以寫入不同的 Configuration 選項(xiàng)配置不同的文件吏奸。每一個(gè) xcconfig 可以配置 Build Settings 里的屬性值, 其實(shí)實(shí)質(zhì)就是通過(guò) xcconfig 去修改 GCC_PREPROCESSOR_DEFINITIONS 的值,這樣我們就可以做到動(dòng)態(tài)配置環(huán)境的需求了陶耍。

現(xiàn)在本地有這么多配置奋蔚,到底哪一個(gè)最終生效呢?打開(kāi)Build 里面的level烈钞,優(yōu)先級(jí)是從左往右泊碑,依次降低的。Resolved = target-level > project-level > 自定義配置文件 > iOS 默認(rèn)配置毯欣。


20170717121849444.jpeg

除了上面的功能以為馒过,還能利用xcconfig動(dòng)態(tài)配置Build Settings里面的很多參數(shù)。這其實(shí)類似于cocopods的做法仪媒。詳情資料請(qǐng)大家自行搜索沉桌。

三谢鹊、利用Targets配置多環(huán)境

其實(shí)使用Scheme和xcconfig就可以實(shí)現(xiàn)多環(huán)境的功能,使用Targets反而顯得更加麻煩留凭。利用Targets可以瞬間大批量產(chǎn)生大量的app佃扼。相關(guān)使用可以查看:使用多Target來(lái)構(gòu)建大量相似App

僅僅只用一套代碼,就可以生產(chǎn)出7個(gè)app蔼夜。7個(gè)app的證書都是不同的兼耀,配置也都不同,但是代碼只需要維護(hù)一套代碼求冷,就可以完成維護(hù)7個(gè)app的目標(biāo)瘤运。

下面來(lái)看一下如何使用Targets來(lái)生成不同的app。


20170717140246032.png

一種方法是完全新建一個(gè)Targets匠题,另外一種方法是復(fù)制原有的Targets拯坟。

其實(shí)第一種方法建立出Targets,之后看你需求是怎么樣的韭山。如果也想是做OEM這種郁季,可以把新建出來(lái)的project刪掉,本地還是維護(hù)一套代碼钱磅,然后在新建的Targets 的Build Phases里面去把本地現(xiàn)有代碼加上梦裂,參數(shù)自己可以隨意配置。這樣也是一套代碼維護(hù)多個(gè)app盖淡。

第二種方法就是復(fù)制一個(gè)原有的Targets年柠,這種做法只用自己去改參數(shù)就可以了。

再來(lái)說(shuō)說(shuō)Targets的參數(shù)褪迟。

由于我們新建了Targets冗恨,相當(dāng)于新建了一個(gè)app了。所以里面的所有的文件全部都可以更改牵咙。包括info.plist派近,源碼引用攀唯,Build Settings……所有參數(shù)都可以改洁桌,這樣就不僅僅局限于修改Scheme和xcconfig,所以之前說(shuō)僅僅配置一個(gè)多環(huán)境用Targets有點(diǎn)興師動(dòng)眾侯嘀,但是它確實(shí)能完成目的另凌。根據(jù)第二章里面我們也提到了,Targets相當(dāng)于流水線戒幔,僅次于Project的地位吠谢,可以想象,有了Targets诗茎,我們沒(méi)有什么不能修改的工坊。

注意點(diǎn)

在開(kāi)發(fā)過(guò)程中遇到比較坑爹的問(wèn)題:證書不使用xcode的Automatically manage signing 的時(shí)候献汗,(環(huán)境不同bundle ID不同的時(shí)候)每個(gè)版本選擇不同的描述文件,需要注意的地方 bundle IDBuild SettingsPackage分欄下的Product Bundle Identifier的為準(zhǔn)王污,要不然選擇描述文件的時(shí)候有問(wèn)題罢吃,就會(huì)提示
The provisioning profile specified in your build settings ("xxx") has an AppID of "com.xxx" which does not match your bundle identifier "com.xxx"
http://blog.csdn.net/l2i2j2/article/details/51661443

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市昭齐,隨后出現(xiàn)的幾起案子尿招,更是在濱河造成了極大的恐慌,老刑警劉巖阱驾,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件就谜,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡里覆,警方通過(guò)查閱死者的電腦和手機(jī)丧荐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)喧枷,“玉大人篮奄,你說(shuō)我怎么就攤上這事「钊ィ” “怎么了窟却?”我有些...
    開(kāi)封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)呻逆。 經(jīng)常有香客問(wèn)我夸赫,道長(zhǎng),這世上最難降的妖魔是什么咖城? 我笑而不...
    開(kāi)封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任茬腿,我火速辦了婚禮,結(jié)果婚禮上宜雀,老公的妹妹穿的比我還像新娘切平。我一直安慰自己,他們只是感情好辐董,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布悴品。 她就那樣靜靜地躺著,像睡著了一般简烘。 火紅的嫁衣襯著肌膚如雪苔严。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天孤澎,我揣著相機(jī)與錄音届氢,去河邊找鬼。 笑死覆旭,一個(gè)胖子當(dāng)著我的面吹牛退子,可吹牛的內(nèi)容都是我干的岖妄。 我是一名探鬼主播,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼寂祥,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼衣吠!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起壤靶,我...
    開(kāi)封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤缚俏,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后贮乳,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體忧换,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年向拆,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了亚茬。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡浓恳,死狀恐怖刹缝,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情颈将,我是刑警寧澤梢夯,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站晴圾,受9級(jí)特大地震影響颂砸,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜死姚,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一人乓、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧都毒,春花似錦色罚、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至涤垫,卻和暖如春姑尺,著一層夾襖步出監(jiān)牢的瞬間竟终,已是汗流浹背蝠猬。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留统捶,地道東北人榆芦。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓柄粹,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親匆绣。 傳聞我的和親對(duì)象是個(gè)殘疾皇子驻右,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

推薦閱讀更多精彩內(nèi)容

  • 前言 談到多環(huán)境,相信現(xiàn)在大多公司都至少有2-3個(gè)app環(huán)境了崎淳,比如Test環(huán)境堪夭,UAT(User Accepta...
    一縷殤流化隱半邊冰霜閱讀 76,004評(píng)論 222 776
  • 歡迎到我的 個(gè)人博客 http://liumh.com 瀏覽此文 與公司 QA 聊天,已不止一次被吐槽說(shuō)移動(dòng)端從開(kāi)...
    CaryaLiu閱讀 4,592評(píng)論 0 16
  • 前言 一個(gè)APP的開(kāi)發(fā)涉及到多種環(huán)境在所難免拣凹,比如Test環(huán)境森爽,UAT(User Acceptance Test)...
    Randy1993閱讀 7,112評(píng)論 4 15
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn)嚣镜,斷路器爬迟,智...
    卡卡羅2017閱讀 134,651評(píng)論 18 139
  • 早晨就開(kāi)始煩躁 窗外 人行道旁 一顆搖擺的樹(shù) 讓我窒息 仿佛嘲笑我 不能生活在她那樣的春夏之交 我卻在嘲笑 初夏...
    Sisii閱讀 116評(píng)論 0 0