如何使用Xcode的Targets來管理開發(fā)和生產(chǎn)版本的構(gòu)建

這篇文章由Eugene Trapeznikov貢獻劫灶。想象一下霞丧,你已經(jīng)完成了應(yīng)用程序的開發(fā)和測試劲妙,現(xiàn)在準(zhǔn)備提交正式版本湃鹊。問題是,一些web服務(wù)的url指向了測試服務(wù)器镣奋,同時API密鑰被配置用于測試環(huán)境币呵。在提交app給蘋果審核前,你需要修改所有這些API密鑰和URL以適應(yīng)生產(chǎn)版本侨颈。這聽起來還好余赢,對吧?但是相較于在開發(fā)環(huán)境和生產(chǎn)環(huán)境之間來回修改相關(guān)數(shù)值肛搬,有沒有更好的方法來處理開發(fā)和生產(chǎn)版本的構(gòu)建没佑?這正是接下來Eugene要和你討論的毕贼。

進入Eugene的教程

對于初學(xué)者來說温赔,有些人可能會奇怪,在App開發(fā)過程中鬼癣,為什么需要使用兩個單獨的數(shù)據(jù)庫和環(huán)境陶贼。原因是當(dāng)你繼續(xù)構(gòu)建新的功能特性或繼續(xù)開發(fā)你的應(yīng)用,你希望區(qū)分開現(xiàn)有的公開版本和生產(chǎn)版本待秃。

標(biāo)準(zhǔn)的軟件開發(fā)實踐是在不同的開發(fā)環(huán)境下開發(fā)不同版本的軟件拜秧,像我們案例中講到的開發(fā)iphone應(yīng)用。應(yīng)用程序的開發(fā)版本通常使用一個不同于生產(chǎn)環(huán)境的數(shù)據(jù)庫(或如分析的其他系統(tǒng))章郁。這就是為什么我們應(yīng)該為不同的環(huán)境中使用單獨的服務(wù)器和數(shù)據(jù)庫枉氮。開發(fā)人員在測試期間通常都使用虛擬圖像或虛擬數(shù)據(jù)。在測試環(huán)境中暖庄,使用諸如 “test comment”, “argharghargh” 和 “one more test comment”之類的測試數(shù)據(jù)并不少見聊替。顯然,你不希望你的真實用戶看到這樣的消息培廓。如果你的應(yīng)用程序使用了一個分析系統(tǒng)的情況下惹悄,你甚至?xí)跍y試階段發(fā)送成千上萬的事件。同樣的,你不會把測試數(shù)據(jù)和生產(chǎn)數(shù)據(jù)放在同一個數(shù)據(jù)庫中肩钠。這就是為什么總是推薦區(qū)分開發(fā)和生產(chǎn)環(huán)境泣港。

在使用兩個獨立的環(huán)境時暂殖,你的應(yīng)用程序需要有一個辦法找出它應(yīng)該連接到的環(huán)境。一種常用的方法是在你的主應(yīng)用代理里定義一個全局變量当纱,它會將您的應(yīng)用程序初始化為開發(fā)或生產(chǎn)模式呛每。

enumenvironmentType?{

casedevelopment,?production

}

let?environment:environmentType?=?.production

switchenvironment?{

case.development:

//?set?web?service?URL?to?development

//?set?API?keys?to?development

print("It's?for?development")

case.production:

//?set?web?service?URL?to?production

//?set?API?keys?to?production

print("It's?for?production")

}

這種方法需要你每次切換環(huán)境時改變?nèi)肿兞俊km然這種方法也許快捷坡氯,方便莉给,但是它有一些重要的限制。首先廉沮,因為我們在開發(fā)和生產(chǎn)兩個環(huán)境中使用一個Bundle ID颓遏,你不能在一臺設(shè)備上安裝應(yīng)用的兩個版本。當(dāng)你需要要測試開發(fā)版本的應(yīng)用程序時滞时,同時仍在該設(shè)備上使用生產(chǎn)版本的應(yīng)用叁幢,這就變的不方便了。此外坪稽,這種方法很有可能將應(yīng)用的開發(fā)版本上傳到應(yīng)用商店曼玩。如果你忘記了改變這個全局變量,你將會上傳錯誤的應(yīng)用給你的用戶窒百。我記得有一次在提交應(yīng)用程序到應(yīng)用商店之前我忘記改變?nèi)肿兞渴蚺校脩粝螺d的是應(yīng)用的開發(fā)版本,這是可怕的篙梢。

在這篇文章中顷帖,我將展示一個更好的方法來區(qū)分開發(fā)和生產(chǎn)構(gòu)建。具體而言渤滞,我們將在Xcode中創(chuàng)建一個開發(fā)的target贬墩。這種方法法適用于新的和現(xiàn)有的大型項目,所以你可以用一個現(xiàn)有的應(yīng)用程序?qū)φ毡窘坛獭?/p>

通過應(yīng)用這種方法妄呕,應(yīng)用的開發(fā)和生產(chǎn)版本將使用相同的基礎(chǔ)代碼陶舞,但可以有不同的圖標(biāo),bundle ID 和指向不同的數(shù)據(jù)庫绪励。發(fā)布和提交過程將會非常簡單肿孵。最重要的是,你的測試人員和經(jīng)理可以在同一設(shè)備上安裝兩個版本的應(yīng)用程序,所以他們完全知道他們在體驗?zāi)膫€版本。

如何創(chuàng)建一個新的Target

所以你如何在Xcode中創(chuàng)建一個開發(fā)的target?我使用示例項目“todo”引導(dǎo)您一步一步完成整個過程疏魏。停做。您也可以使用自己的項目并按照步驟:

1. 在項目的導(dǎo)航面板進入項目設(shè)置。在Targets區(qū)域下蠢护,右鍵單擊現(xiàn)有目標(biāo)并選擇 `Duplicate` 復(fù)制現(xiàn)有的目標(biāo)雅宾。

2.Xcode會詢問你新的target是否是為iPad開發(fā)。對于本教程,我們只是選擇“Duplicate Only”。

提示:如果您的項目支持通用設(shè)備眉抬,Xcode不會提示上述消息贯吓。

3.現(xiàn)在我們有一個名為`todo copy`的新的target和build scheme。重命名并使之更容易理解蜀变。

在Targets列表中選擇新的target悄谐。按Enter鍵編輯文本,添加一個更合適的名字库北。我更傾向于“todo Dev”爬舰。你可以自由選擇任何你喜歡的名字。

接下來寒瓦,找到“Manage Schemes…”情屹,選擇您在步驟1中創(chuàng)建的shceme,并按“輸入”,使scheme的名稱和新的target的名稱相同(這是你為新的target所選擇的名字)

4. 步驟4是可選的杂腰,但強烈推薦垃你。如果你想簡單地區(qū)分開發(fā)和生產(chǎn)版本構(gòu)建,你應(yīng)該為每個版本使用單獨的icon和啟動頁喂很。這將使測試人員更清晰地知道正在使用哪個app,防止上傳開發(fā)版本惜颇。

跳到 `Assets.xcassets` 添加一個新的圖標(biāo)。右擊圖標(biāo) >?App Icons & Launch Images?>?New iOS App Icon. 新圖標(biāo)重命名為“AppIcon-Dev”同時添加自己的圖片少辣。

5.現(xiàn)在回到項目設(shè)置,選擇您的開發(fā)target凌摄,并改變Bundle Identifier。你可以簡單地將“Dev”追加到原來的ID上漓帅。如果執(zhí)行了步驟4锨亏,請確保更改應(yīng)用app icon,設(shè)置為在上一步中創(chuàng)建的煎殷。

6. Xcode會自動為你的target添加plist文件(如todo copy-Info.plist)屯伞。你可以在項目的根文件夾找到它。將它從“copy”重命名為“Dev”,并將它放在原始的plist文件下豪直。這里你將更容易管理文件。

7. 現(xiàn)在打開你開發(fā)target的“Build Settings”珠移,滾動到“Packaging”弓乙,并將值改為開發(fā)的plist文件(todo Dev.plist)。

8. 最后钧惧,我們會為生產(chǎn)和開發(fā)target配置預(yù)處理宏/編譯器標(biāo)識暇韧。之后我們就可以使用該標(biāo)識在我們的代碼來檢測應(yīng)用程序正在運行的版本。

對于Objective-C的項目浓瞪,去到`Build Settings`下`Apple LLVM 7.0 - Preprocessing`懈玻。拓展`Preprocessor Macros`在Rebug和Release區(qū)域添加一個變量。對于開發(fā)target(即todo Dev)乾颁,將該值設(shè)置為`DEVELOPMENT = 1`涂乌。另一個艺栈,將值設(shè)為`DEVELOPMENT=0`來表示生產(chǎn)版本。

對于swift的項目湾盒,編譯器不再支持預(yù)處理指令湿右。作為替代,它使用編譯時的屬性和build配置罚勾。選中開發(fā)target毅人,添加一個標(biāo)識表示開發(fā)版本。找到`Build Setting`往下滾動到`Swift Compiler - Custom Flags`部分尖殃。將值設(shè)為`-DDEVELOPMENT`表示這個target作為開發(fā)版本丈莺。

現(xiàn)在,您已經(jīng)創(chuàng)建并配置了開發(fā)target送丰,下一步呢场刑?

使用Target和宏

根據(jù)已配置的宏DEV_VERSION,我們可以在代碼中利用它動態(tài)地編譯項目蚪战。下面是一個簡單的例子:

Objective-C:

#ifDEVELOPMENT

#define?SERVER_URL?@"http://dev.server.com/api/"

#define?API_TOKEN?@"DI2023409jf90ew"

#else

#define?SERVER_URL?@"http://prod.server.com/api/"

#define?API_TOKEN?@"71a629j0f090232"

#endif

Objective-C中你可以使用`#if`檢查`DEVELOPMENT`的環(huán)境牵现,并相應(yīng)的設(shè)置URLs/ API密鑰。

Swift:

#ifDEVELOPMENT

let?SERVER_URL?="http://dev.server.com/api/"

let?API_TOKEN?="DI2023409jf90ew"

#else

let?SERVER_URL?="http://prod.server.com/api/"

let?API_TOKEN?="71a629j0f090232"

#endif

Swift中你仍然可以使用`#if`判定build的參數(shù)動態(tài)編譯邀桑。然而瞎疼,除了使用`#define`定義基本常量,在swift中我們也可以用`let`定義一個全局常量壁畸。

提示:通常贼急,你會把上面的代碼放在app delegate中。但這最終是取決于你在哪里初始化應(yīng)用程序設(shè)置捏萍。

現(xiàn)在太抓,當(dāng)您選擇“todo Dev”scheme運行項目,你創(chuàng)建開發(fā)版本會自動將服務(wù)器的配置設(shè)置為開發(fā)環(huán)境×铊荆現(xiàn)在走敌,您可以上傳開發(fā)版本到TestFlight 或 HockeyApp供測試人員和管理人員來測試。

接著如果你需要創(chuàng)建一個生產(chǎn)版本逗噩,您可以簡單地選擇"todo"scheme掉丽。不需要更改代碼。

管理多個target的一些注意事項

1.當(dāng)你添加新的文件到項目中异雁,不要忘記選擇兩個target捶障,以保持你的代碼同步在兩個版本。

2.如果你使用的CocoaPods纲刀,不要忘了添加新的target到你的podfile中项炼。您可以使用`link_with`指定多個target。您可以進一步細(xì)節(jié)請查閱的CocoaPods文檔。你的podfile看起來是這樣的:

source'https://github.com/CocoaPods/Specs.git'

platform?:ios,'7.0'

workspace'todo'

link_with'todo','todo?Dev'

pod'Mixpanel'

pod'AFNetworking'

3.如果你使用持續(xù)集成系統(tǒng)锭部,如Travis CIJenkins暂论,別忘了配置兩個target的build和deliver。

你對這個教程有什么想法空免?如何管理你的開發(fā)和生產(chǎn)構(gòu)建空另?給我留言評論分享您的想法

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市蹋砚,隨后出現(xiàn)的幾起案子扼菠,更是在濱河造成了極大的恐慌,老刑警劉巖坝咐,帶你破解...
    沈念sama閱讀 218,607評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件循榆,死亡現(xiàn)場離奇詭異,居然都是意外死亡墨坚,警方通過查閱死者的電腦和手機秧饮,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來泽篮,“玉大人盗尸,你說我怎么就攤上這事∶背牛” “怎么了泼各?”我有些...
    開封第一講書人閱讀 164,960評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長亏拉。 經(jīng)常有香客問我扣蜻,道長,這世上最難降的妖魔是什么及塘? 我笑而不...
    開封第一講書人閱讀 58,750評論 1 294
  • 正文 為了忘掉前任莽使,我火速辦了婚禮,結(jié)果婚禮上笙僚,老公的妹妹穿的比我還像新娘芳肌。我一直安慰自己,他們只是感情好味咳,可當(dāng)我...
    茶點故事閱讀 67,764評論 6 392
  • 文/花漫 我一把揭開白布庇勃。 她就那樣靜靜地躺著,像睡著了一般槽驶。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上鸳兽,一...
    開封第一講書人閱讀 51,604評論 1 305
  • 那天掂铐,我揣著相機與錄音,去河邊找鬼。 笑死全陨,一個胖子當(dāng)著我的面吹牛爆班,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播辱姨,決...
    沈念sama閱讀 40,347評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼柿菩,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了雨涛?” 一聲冷哼從身側(cè)響起枢舶,我...
    開封第一講書人閱讀 39,253評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎替久,沒想到半個月后凉泄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,702評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡蚯根,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,893評論 3 336
  • 正文 我和宋清朗相戀三年后众,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片颅拦。...
    茶點故事閱讀 40,015評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡蒂誉,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出距帅,到底是詐尸還是另有隱情右锨,我是刑警寧澤,帶...
    沈念sama閱讀 35,734評論 5 346
  • 正文 年R本政府宣布锥债,位于F島的核電站陡蝇,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏哮肚。R本人自食惡果不足惜登夫,卻給世界環(huán)境...
    茶點故事閱讀 41,352評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望允趟。 院中可真熱鬧恼策,春花似錦、人聲如沸潮剪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,934評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽抗碰。三九已至狮斗,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間弧蝇,已是汗流浹背碳褒。 一陣腳步聲響...
    開封第一講書人閱讀 33,052評論 1 270
  • 我被黑心中介騙來泰國打工折砸, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人沙峻。 一個月前我還...
    沈念sama閱讀 48,216評論 3 371
  • 正文 我出身青樓睦授,卻偏偏與公主長得像,于是被迫代替她去往敵國和親摔寨。 傳聞我的和親對象是個殘疾皇子去枷,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,969評論 2 355

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