Xcode多環(huán)境配置

Xcode多環(huán)境配置一共有3種形式:

  • Target
  • Scheme
  • xcconfig

Project:包含了項目所有的代碼购笆、資源文件同欠、所有信息行您。(一個項目是多個project的集合)
Target:對指定代碼和資源文件的具體構(gòu)建方式娃循。(指定某些代碼如何生成ipa包捌斧,類似打工人的角色)
Scheme:對指定Target的環(huán)境配置。(配置編譯環(huán)境變量)
這也就是我們修改一些配置的時候需要選中Target再去修改的原因姓迅。

多Target配置

在項目中選中Target復(fù)制就生成新的Target了丁存。

image.png

在這里復(fù)制后并沒有產(chǎn)生額外代碼解寝,只是復(fù)制了一個新的構(gòu)建模式聋伦。
image.png

相當(dāng)于可以直接分別配置Info.plist文件兵拢,在Target中修改bundleId后就相當(dāng)于兩個Target是兩個App了说铃。
同時可以在Preprocessor Macros中配置一些宏定義用于代碼中區(qū)分Target截汪。
image.png

比如在OCSwift混編的時候,在OC中導(dǎo)入頭文件就可以用這個宏來處理:

#if DEV
#import "TestMutableConfig_dev-Swift.h"
#else
#import "TestMutableConfig-Swift.h"
#endif

對應(yīng)的Swift文件:

image.png

Swift中也可以用Swift宏來處理:
Other Swift Flags中配置變量- D DEV(空格有沒有都行)
image.png

#if DEV
func log(message: String) {
    print(message)
}
#endif
?  ~  swiftc --help | grep -- '-D'
-D <value>              Marks a conditional compilation flag as true

Target方式配置多環(huán)境
1.會生成多個Info.plist文件;
2.配置比較繁瑣暑椰,需要同步配置容易混亂
那么對于多Target的場景是可以在Build Phases中控制要編譯的文件和資源一汽。

image.png

多scheme配置

scheme默認(rèn)有DebugReleaseconfig我們可以按需添加。在Target中添加變量的時候已經(jīng)用到過了监憎。
配置在Project -> Info -> Configurations

image.png

比如我們有appStore包,有企業(yè)包褐筛。那么各復(fù)制一份對應(yīng)的DebugRelease(最好是配置完成后再復(fù)制)
image.png

運行/打包的時候選擇對應(yīng)的Scheme就可以了。
image.png

這種情況下運行不同配置的時候需要來回切換笤虫。
可以通過創(chuàng)建Scheme對應(yīng)不同config
image.png

image.png

這個時候只需要切換Scheme運行就可以了。
image.png

比如我們上傳打包ipa的時候,有時候會錯將debug模式下的包上傳上去榨了,尤其是在發(fā)灰度包的時候龙屉。這里有兩個方案:
1.通過config配置转捕。
2.打包的時候通過腳本修改info.plist文件增加一個變量瓜富。

release包賦值為0与柑,debug包賦值為1价捧。這樣在上傳ipa包的時候后端讀取Info.plist做判斷结蟋,debug包直接報錯不讓傳嵌屎。
這里實現(xiàn)以下方式1:
Targets -> Build Settings -> + -> Add User-Defined Setting

image.png

添加一個IPAFLAG植榕,release模式下是1尊残,debug模式下是0:
image.png

Info.plist文件中增加配置:
image.png

到這里就完成了

  • User-Defined添加配置;
  • Info.plist暴露配置的目的慰毅。

在代碼中測試下:

    NSString *infoPath = [[NSBundle mainBundle] pathForResource:@"Info" ofType:@"plist"];
    NSDictionary *infoDic = [[NSDictionary alloc] initWithContentsOfFile:infoPath];
    NSLog(@"IPAFLAG = %@",infoDic[@"IPAFLAG"]);

Debug下:

 IPAFLAG = 1

當(dāng)然也可以配置app圖標(biāo):
Assets.xcassets中添加不同的資源文件

image.png

Scheme還可以控制傳遞參數(shù)等事富,一般不常用统台。

image.png

Scheme情況只需要在一個build setting中就能完成配置了,比多Target方便好維護贵扰。
缺點是還需要在build setting中設(shè)置戚绕。

xcconfig

這個我們平時都接觸到了舞丛,可能好多人沒有注意到球切,用的最廣泛的就是cocoapods吨凑。
比如Other Linker Flags鸵钝、Search Paths蒋伦。

image.png

image.png

那么Cocoapods是怎么配置的呢?
image.png

就是使用xcconfig配置的:

FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking"
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking/AFNetworking.framework/Headers"
LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
OTHER_LDFLAGS = $(inherited) -framework "AFNetworking"
PODS_BUILD_DIR = ${BUILD_DIR}
PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
PODS_ROOT = ${SRCROOT}/Pods
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES

xcconfigkey-value的形式配置的。那么怎么對應(yīng)到xcconfig文件的呢?

image.png

Configurations中對應(yīng)配置的申屹。

配置自己的xcconfig文件

新建 -> Configuration Settings File

image.png

命令規(guī)則為:以所在目錄開頭-工程名稱.config名稱/環(huán)境名稱,比如Config-TestMutableConfig.Debug
image.png

接著可以在config中選擇配置
image.png

  • 1中設(shè)置是對整個Project生效。
  • 2中設(shè)置是對Target生效决乎。

還是以IPAFLAG為例构诚,以xcconfig的方式配置范嘱。
plist中的配置不變彤侍,User-Defined配置刪除

    <key>IPAFLAG</key>
    <string>${IPAFLAG}</string>

Config-TestMutableConfig.Debug.xcconfig

IPAFLAG = 1

Config-TestMutableConfig.Release.xcconfig

IPAFLAG = 0

代碼中讀取下:

    NSString *infoPath = [[NSBundle mainBundle] pathForResource:@"Info" ofType:@"plist"];
    NSDictionary *infoDic = [[NSDictionary alloc] initWithContentsOfFile:infoPath];
    NSLog(@"IPAFLAG = %@",infoDic[@"IPAFLAG"]);
IPAFLAG = 1

這樣配置更清晰盏阶,便于管理名斟。

xcconfig其它用途

處了配置變量還可以配置Build Setting中的配置:

IPAFLAG = 1
//ld
OTHER_LDFLAGS = -framework "AFNetworking"

image.png

編譯后雖然報錯但是已經(jīng)配置進來了闷袒。那么Build Setting中的配置都可以用xcconfig文件來管理了囊骤。
OTHER_LDFLAGSbuild setting中的縮寫也物,本質(zhì)是key-value滑蚯。具體的key可以在xcodebuildsettings中查找告材。
image.png

image.png

IPAFLAG = 1

//ld配置連接器
//OTHER_LDFLAGS為build中的縮寫
OTHER_LDFLAGS = -framework "AFNetworking"

HEADER_SEARCH_PATHS = /usr/info

image.png

可以看到編譯后就配置進去了绢慢。所以通過xcconfig文件就完成了多環(huán)境配置的場景胰舆。

所以xcconfig配合scheme以及config就完成了項目的多環(huán)境配置缚窿。并且xcconfig可以直接復(fù)制到其它項目復(fù)用倦零。

沖突解決

前面說過cocoapods會創(chuàng)建xcconfig文件扫茅,在上面的例子中就和自己創(chuàng)建的沖突了葫隙。因為Configurations中只能指定一個。
當(dāng)然Cocoapods安裝的時候不會覆蓋我們在Configurations配置的焰手。

image.png

可以看到在pod install的時候Cocoapods給警告了:

[!] CocoaPods did not set the base configuration of your project 
because your project already has a custom config set. 
In order for CocoaPods integration to work at all, please either set the base configurations of the target `TestMutableConfig` to `Target Support Files/Pods-TestMutableConfig/Pods-TestMutableConfig.debug.xcconfig` 
or include the `Target Support Files/Pods-TestMutableConfig/
Pods-TestMutableConfig.debug.xcconfig` in your build configuration 
(`TestMutableConfig/Config/Config-TestMutableConfig.Debug.xcconfig`).

在這里已經(jīng)給提示讓我們導(dǎo)入了。

#include "Target Support Files/Pods-TestMutableConfig/Pods-TestMutableConfig.debug.xcconfig"

導(dǎo)入后依然報錯:

image.png

找不到目錄怀喉,查看文件位置發(fā)現(xiàn)少了Pods/加上后編譯成功

#include "Pods/Target Support Files/Pods-TestMutableConfig/Pods-TestMutableConfig.debug.xcconfig"
IPAFLAG = 1

//ld配置連接器
//OTHER_LDFLAGS為build中的縮寫
OTHER_LDFLAGS = -framework "AFNetworking"

再次pod install就沒有警告了

image.png

那么還存在一個問題书妻,自己配制的xcconfigcocoapods生成的xcconfig如果有相同變量會怎么樣?比如上面的OTHER_LDFLAGS躬拢。
可以看到生效的是自己配置的躲履。
image.png

cocoapods的配置中有一個繼承$(inherited)估灿,這里的繼承實際上是兩個字符串拼接起來崇呵。
image.png

所以自己配制的也加上$(inherited)

#include "Pods/Target Support Files/Pods-TestMutableConfig/Pods-TestMutableConfig.debug.xcconfig"
IPAFLAG = 1

//ld配置連接器
//OTHER_LDFLAGS為build中的縮寫
OTHER_LDFLAGS = $(inherited) -framework "AFNetworking"

可以看到繼承過來了


image.png

代碼中調(diào)用下:


image.png

編譯成功。

推薦使用scheme + xcconfig配置管理項目環(huán)境馅袁。當(dāng)然在build setting中設(shè)置的并不會被覆蓋(不同名,同名可以繼承荒辕,如果是值key相同會覆蓋后面有總結(jié)優(yōu)先級)

xcconfig配置總結(jié)

key-value 組成

配置文件由一系列鍵值分配組成:

BUILD_SETTING_NAME = value

注釋

xcconfig文件只有一種注釋方式//

//

那么這里就有一個問題了汗销,如果我們要配置一個域名該怎么辦呢?比如:

HOST_URL = https://127.0.0.1

可以通過中間值解決:

TEMP=/
HOST_URL = https:${TEMP}/127.0.0.1

include導(dǎo)入其他設(shè)置

可以通過include關(guān)鍵字導(dǎo)入其他的xcconfig內(nèi)的配置抵窒。通過include關(guān)鍵字后接上雙引號:

#include "Other.xcconfig"

在引入的文件時弛针,如果是以/開頭,代表絕對路徑:

#include "/Users/zaizai/Desktop/TestMutableConfig/Pods/Target Support Files/Pods-TestMutableConfig/Pods-TestMutableConfig.debug.xcconfig"

相對路徑李皇,以${SRCROOT}路徑為開始:

#include "Pods/Target Support Files/Pods-TestMutableConfig/Pods-TestMutableConfig.debug.xcconfig"

變量

變量定義削茁,按照OC命名規(guī)則,僅由大寫字母掉房,數(shù)字和下劃線_組成茧跋,原則上大寫,也可以不卓囚。字符串可以是"也可以是'號瘾杭。

  1. xcconfig中定義的變量與Build Settings的一致,會發(fā)生覆蓋哪亿≈嗨福可以通過$(inherited)讓當(dāng)前變量繼承變量原有值。(當(dāng)然對于系統(tǒng)的key最好都加上$(inherited)`)
//A config
OTHER_LDFLAGS = -framework SDWebImage
//B config
OTHER_LDFLAGS = $(inherited) -framework AFNetworking
//build setting中
// OTHER_LDFLAGS = -framework SDWebImage -framework AFNetworking

??:有部分變量不能通過xcconfig配置到Build Settings中蝇棉。如:配置PRODUCT_BUNDLE_IDENTIFIER不起作用讨阻。

  1. 引用變量,$()${}兩種寫法都可以
VALUE=HotpotCat

KEY1=$(VALUE)
KEY2=${VALUE}
  1. 條件變量篡殷,根據(jù)SDK钝吮、ArchConfigration對設(shè)置進行條件化:
// 指定`Configration`是`Debug`
// 指定`SDK`是模擬器,還有iphoneos*、macosx*等
// 指定生效架構(gòu)為`x86_64`
OTHER_LDFLAGS[config=Debug][sdk=iphonesimulator*][arch=x86_64]= $(inherited) -framework "HotpotCat"

??:在Xcode 11.4及以后版本搀绣,可以使用default來指定變量為空時的默認(rèn)值飞袋。

$(BUILD_SETTING_NAME:default=value)

優(yōu)先級(高->低)

  • 手動配置Target Build Settings;
  • Target中配置的xcconfig文件;
  • 手動配置Project Build Settings;
  • Project中配置的xcconfig文件。

資料

xcodebuildsettings

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末链患,一起剝皮案震驚了整個濱河市巧鸭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌麻捻,老刑警劉巖纲仍,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異贸毕,居然都是意外死亡郑叠,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門明棍,熙熙樓的掌柜王于貴愁眉苦臉地迎上來乡革,“玉大人,你說我怎么就攤上這事摊腋》邪妫” “怎么了?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵兴蒸,是天一觀的道長视粮。 經(jīng)常有香客問我,道長橙凳,這世上最難降的妖魔是什么蕾殴? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮岛啸,結(jié)果婚禮上钓觉,老公的妹妹穿的比我還像新娘。我一直安慰自己值戳,他們只是感情好议谷,可當(dāng)我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著堕虹,像睡著了一般卧晓。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上赴捞,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天逼裆,我揣著相機與錄音,去河邊找鬼赦政。 笑死胜宇,一個胖子當(dāng)著我的面吹牛耀怜,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播桐愉,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼财破,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了从诲?” 一聲冷哼從身側(cè)響起左痢,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎系洛,沒想到半個月后俊性,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡描扯,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年定页,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片绽诚。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡典徊,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出憔购,到底是詐尸還是另有隱情宫峦,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布玫鸟,位于F島的核電站,受9級特大地震影響犀勒,放射性物質(zhì)發(fā)生泄漏屎飘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一贾费、第九天 我趴在偏房一處隱蔽的房頂上張望钦购。 院中可真熱鬧,春花似錦褂萧、人聲如沸押桃。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽唱凯。三九已至,卻和暖如春谎痢,著一層夾襖步出監(jiān)牢的瞬間磕昼,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工节猿, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留票从,地道東北人。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像峰鄙,于是被迫代替她去往敵國和親浸间。 傳聞我的和親對象是個殘疾皇子渗蟹,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,792評論 2 345

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