OS開發(fā)進(jìn)階:一、多環(huán)境配置

實際使用場景:

  1. debug模式和release模式的一些配置不一樣,比如開發(fā)環(huán)境訪問的后臺服務(wù)器和線上版本訪問的服務(wù)器地址不一樣。
  2. 發(fā)布開發(fā)版程序AppIcon不同,包含搶鮮版或者體驗版的特有圖標(biāo)

通??梢詣?chuàng)建一個變量,保存開發(fā)版服務(wù)器地址,然后再復(fù)制創(chuàng)建同一個變量名保存線上版服務(wù)器地址。開發(fā)或者發(fā)布的時候根據(jù)需要,將需要的打開,不需要的注釋。這樣來回切換,達(dá)到匹配相應(yīng)服務(wù)器的結(jié)果。這種方式雖然可以解決問題,但是不夠優(yōu)雅,稍微一個不留神,就會出錯,如果不同的環(huán)境有多個不同的參數(shù),那更得小心翼翼,提心吊膽的感覺是真難受。

那么如何優(yōu)雅的解決這個問題?

這里提供3種方式:

  1. 通過多target的方式
  2. 通過配置變量configurations,Scheme環(huán)境變量的配置達(dá)到多環(huán)境的目的
  3. xcconfig文件,通過xcconfig的形式將對應(yīng)的配置寫到相應(yīng)的文件里面,通過文件管理,更清晰一些,改動的幅度更小一些,同時配合git,將一些文件隱藏起來

隨便打開一個項目代碼,可能打開的是一個project或者一個workspace。那么project在我們開發(fā)中,在我們xcode中到底是什么東西?在Scheme中選擇環(huán)境debug或者release又是代表什么意思呢?

先介紹一下xcode幾個常見的名詞

  • Project:包含了項目所有的代碼,資源文件,所有信息。
  • Target:對指定代碼和資源文件的具體構(gòu)建方式。
  • Scheme:對指定Target的環(huán)境配置。
  • xcconfig:將配置寫到對應(yīng)的文件中
  • workSpace:是多個project的合集。

所有的開發(fā)都是面向project,它是一個大的集合,包含了所有內(nèi)容。Target指定某些代碼來如何生成IPA包,Scheme作為一個監(jiān)控,通過它來配置你編譯時候的環(huán)境變量。Scheme中可以選擇決定target中是debug起作用還是release起作用。

第一部分 通過多Target實現(xiàn)多環(huán)境

第一步:新建iOS項目.png

第二步:復(fù)制一個target.png

第三步:修改FristDemo-dev的bundle ID.png

第四步:修改plist文件名稱.png

復(fù)制出的.plist文件是絕對路徑。而且包含copy,這顯然要做修改。


第五步:新建AppIcon-Dev.png

第六步:設(shè)置新的AppIcon起效.png

第七步:修改target中的plist.png

對于有強(qiáng)迫癥的我,還做了兩步:將plist文件的路徑改為相對路徑。修改Scheme的名稱,帶copy字樣太難看了。


plist文件的相對路徑.png

進(jìn)入manage Scheme.png
修改Scheme名稱.png

準(zhǔn)備工作就緒。通過選擇不同的Scheme,運(yùn)行不同的target,在手機(jī)上會生成兩個App,而且displayName和AppIcon已經(jīng)變了。目前是兩個target操作同一份代碼。如果想在Dev模式下執(zhí)行不同的代碼,應(yīng)該怎么做?可以通過宏定義,預(yù)先定義宏。

OC中可以在 target 的 Preprocessor Macros 里設(shè)置。preprocessor macros的意思就是 預(yù)處理器宏。


預(yù)處理器宏設(shè)置.png

設(shè)置新的變量Dev.png

設(shè)置Release模式下Dev為0.png

測試Dev是否生效.png

OC下的多環(huán)境配置通過多Target的方式處理完畢。

如果是Swift項目呢,或者是OC和Swift的混編項目要怎么通過多Target的方式處理呢?

在剛才項目中新建一個swift文件,讓xcode給我們自動創(chuàng)建一個橋接器。新建兩個Swift的UIViewController,分別命名為SecondViewController和ThirdViewController,現(xiàn)在想讓FirstDemo的viewdidload進(jìn)入SecondViewController,F(xiàn)irstDemo-Dev的viewdidload進(jìn)入ThirdViewController。

第一步:新建一個swift文件.png

默認(rèn)新建一個swift文件橋接器.png

開啟混編Defines module改為Yes.png

檢查Product Module Name是否為工程名FirstDemo-Dev

不同的target測試環(huán)境.png

不同的target測試環(huán)境2.png

到這里就可以實現(xiàn),運(yùn)行不同的target進(jìn)入到不同的ViewController。


進(jìn)入不同Target顯示不同VC的代碼.png
Swift Flags設(shè)置.png

選中 target --> Build Settings --> 搜索 Swift Compiler - Custom Flags
展開 Active Compilation Conditions 進(jìn)行設(shè)置,只能寫名稱:TEST, 不能像OC一樣設(shè)置TEST=1
展開 Other Swift Flags 同樣可以設(shè)置 TEST,需要這樣寫:-D TEST,填完后是 -D 和 TEST 分成兩行的,(如果項目中用到了 CocoaPods 可以參考它也是這樣的)
-D的含義:就是將聲明的變量設(shè)置為TRUE。

如果是 OC 和 Swift 混編的項目,OC也需要用到,則還是在 Preprocessor Macros 里添加一遍。也就是說OC中的預(yù)定義宏和Swift中是完全分開,無法共用的。


swift中的OC預(yù)定義宏無法使用.png

總結(jié):1.步驟太多,操作繁瑣2.存在多個plist文件,預(yù)定義宏變量相互對應(yīng)關(guān)系復(fù)雜,稍有不慎,便會弄錯

第二部分 通過Scheme實現(xiàn)多環(huán)境

Scheme是什么?就是控制環(huán)境變量,讓項目中哪個變量起作用。常見的有debug和release。


打開Scheme.png

Scheme環(huán)境變量選擇.png

可以添加自己的configuration.png
創(chuàng)建一個新的configuration.png

改名為Beta.png

再到Scheme中查看就存在Beta環(huán)境變量了.png

Target就是往編譯的時候添加參數(shù),指明編譯的方式,告訴編譯器代碼怎么編譯成相應(yīng)的結(jié)果。并不是控制或者改變一些什么東西。


所有可配置的選項都變成了3種.png

在Scheme中切換到哪一種,就會使用Build Settings中對應(yīng)的相關(guān)設(shè)置。Scheme的設(shè)置是全局的Configuration的設(shè)置。

有沒有一種方式不用去手動切換Scheme中的3個Beta,Debug和Release?

第一步:用manage Scheme新建一個Scheme.png

第二步:選擇target創(chuàng)建不同名稱的Scheme.png

第三步:新建兩個Scheme分別命名為Debug和Beta.png

第四步:將不同的Scheme設(shè)為對應(yīng)到的Configuration.png

這樣有什么好處?針對先前開發(fā)環(huán)境和發(fā)布環(huán)境不同的服務(wù)器地址。我們可以有新的辦法。


添加一個用戶定義變量.png

新建Host_URL變量.png

Host_URL變量的根據(jù)需要已經(jīng)設(shè)置成了我們想要的狀態(tài),那么如何去讀取到這個值?我們可以在info.plist中,設(shè)置一個變量進(jìn)行讀取,這樣來達(dá)到暴露出來供程序使用的目的。


info.plist中設(shè)置獲取Host_URL變量.png
NSString *path = [NSBundle.mainBundle pathForResource:@"Info" ofType:@"plist"];
NSDictionary *infoDic = [[NSDictionary alloc] initWithContentsOfFile:path];
NSLog(@"%@",infoDic[@"HOST_URL"]);
可以在Build Setting中設(shè)置達(dá)到不同AppIcon的目的.png

這樣就達(dá)到了多環(huán)境的目的。
總結(jié):比上面多target方式要好,不用創(chuàng)建多target,只需要在一個Build Setting里面就能配置。有多少個環(huán)境,就可以創(chuàng)建多少個Configuration。但還是有個弊端,還是必須要在Build Setting中進(jìn)行相關(guān)的配置。

我們正常的一個項目,通過Cocoapods進(jìn)行引用的時候,對應(yīng)的我們的target,Build Setting中Other Link Flags,Path to Link Map File,Framework Search Paths等等都是有參數(shù)的,如果使用Scheme這種方式,我們還是要在Build Setting中不停的配置。

那么能否通過一個文件的方式,來對整個Build Setting中我們想做的修改,做統(tǒng)一的管理呢?放在一起,放在一個文件。

第三部分 xcconfig文件管理Build Setting多環(huán)境配置

Cocoapods中使用的就是xcconfig文件,當(dāng)我們通過Cocoapods導(dǎo)入一個項目的時候,Cocoapods通常會給我們生成兩個文件。一個為“項目名.debug.xcconfig”,一個為“項目名.release.xcconfig”。實際上是根據(jù)Configuration中的配置生成的。


根據(jù)Configuration個數(shù)創(chuàng)建出3個xcconfig.png

Configuration對應(yīng)的cocoapods生成的3個文件.png

xcconfig文件也可以切換.png

xcconfig的本質(zhì)是一個Key-Value形式。

創(chuàng)建我們自己的XCConfig文件
注意:以保存的目錄作為開頭XCConfig,-拼上APP的名稱FirstDemo,拼上環(huán)境debug。

創(chuàng)建自己的XCConfig文件.png

創(chuàng)建自己的XCConfig文件2.png

讓我們自己生成的xcconfig生效.png

準(zhǔn)備工作完成,如何實現(xiàn)多環(huán)境配置呢?

在xcconfig中開始寫我們需要做區(qū)分的內(nèi)容。比如添加一個端口號,在debug.xcconfig中加入PORT = 8080,在release.xcconfig中假如PORT = 5001。
一樣需要在info.plist中暴露出來。

測試結(jié)果.png

編譯過后,再觀察Build Setting。

xcconfig會自動幫我們管理Build Setting.png

xcconfig寫入的規(guī)則是什么?與Build Setting中什么字段相對應(yīng)??梢栽谔O果官方提供的資料里面查。Xcode Build Settings

直接搜xcconfig與build setting的對應(yīng)關(guān)系.png

總結(jié):完美的實現(xiàn)在xcconfig文件中對Build Setting中參數(shù)的設(shè)置。

額外部分

1.在自己創(chuàng)建的xcconfig中引入pod生成的xcconfig文件:

#include "Pods/Target Support Files/Pods-FirstDemo/Pods-FirstDemo.debug.xcconfig"
xcconfig路徑來由.png

啊哈,在這里運(yùn)行的時候出現(xiàn)一個錯誤:

dyld: Library not loaded: @rpath/AFNetworking.framework/AFNetworking
  Referenced from: /private/var/containers/Bundle/Application/F4E7F2A4-56BA-4E73-AA37-8349B2791333/FirstDemo-Dev.app/FirstDemo-Dev
  Reason: image not found
dyld: launch, loading dependent libraries
DYLD_LIBRARY_PATH=/usr/lib/system/introspection
DYLD_INSERT_LIBRARIES=/Developer/usr/lib/libBacktraceRecording.dylib:/Developer/usr/lib/libMainThreadChecker.dylib:/Developer/Library/PrivateFrameworks/DTDDISupport.framework/libViewDebuggerSupport.dylib

這里先不理會,但是證明了一個事情,那就是加載pod的xcconfig是起效的。

2.xcconfig文件沖突解決
自己創(chuàng)建的xcconfig文件中存在pod生成的xcconfig文件中相同的字段,那么就會覆蓋pod中的字段,因此要想兩個文件中的字段都生效需要使用繼承標(biāo)識:
$(inherited)

$(inherited)繼承已有設(shè)置,防止沖突.png

3.URL變量中存在//,后面的字符串會被當(dāng)做注釋

// 通過定義一個變量來解決
SLASH =/
HOST_URL = http:${SLASH}/192.168.1.100

4.條件設(shè)置

OTHER_LDFLAGS[config=Debug][sdk=iphonesimulator*][arch=x86_64] = $(inherited) -framework "AFNetworking"

經(jīng)過上述條件設(shè)置后AFNetworking庫僅會在Debug、模擬器、X86_64架構(gòu)下編譯
[sdk=iphoneos*]表示真機(jī)

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容