這里我們會介紹三種,在充分了解前兩種的基礎上,建議大家在開發中靈活使用第三種方法。當然,大家在熟練的情況也可以根據實際情況自己組合使用
在講解多環境配置之前我們先來認識一下,我們在Xcode常見的一些名詞,都代表什么意思?
-
Project
:包含了項目所有的代碼,資源文件,所有信息。 -
Target
:對指定代碼和資源文件的具體構建方式。 -
Scheme
:對指定Target的環境配置。
首先我們來看一個熟悉的東西:
image.png
相信大家都會通多上面修改Configuration
的方式來切換Debug
和Release
的開發環境。但是僅僅是這樣并不能滿足我們日常的開發需求,下面我們來介紹三種Xcode的多環境配置,希望可以在日常的開發中給大家帶來方便,增加效率。
方法一:通過增加Target
我們知道,Target
是對指定代碼和資源文件的具體構建方式。那么理論上我們知道復制一份Target
出來,然后在不同的Target
下,設置不同的參數配置不就可以了嗎!
下面我們來配置一下:
1、首先我們針對對應的Target
,制作一個副本
2、制作完成之后,我們會發現工程里面多了一個
Target
和一個Info.plist
文件,同時也會多一個Scheme
。3、我們可以通過修改Bundle Indentifier
、Info.plist
和Scheme
名稱來進行區分
?? 注意,修改外Info.plist
文件名之后,一定要在對應的Build Settings
里面修改Info.plist
路徑
- 我們接著講一下,
Target
中預定義宏的的設置
我們再testDebug
中設置自定義的宏:
image.png
使用如下:
if (TEST_DEBUG) {
NSLog(@"Debug");
} else {
NSLog(@"Release");
}
注意 ?? :此時TEST_DEBUG
我們并不能在test
中使用,因為我們只在testDebug
設置了;那么當我們切換到test
環境中的時候,就會報錯:(這里要注意,對個Target
操作的只有一套代碼)
這時候我們只需要在
test
環境下也設置同樣名字的宏就可以了,宏對應的值設置成不同的,就可以在代碼里面區分不同的環境,執行不同的指令了。
-
Swift環境中設置
Other Swift Flags
,混編情況下也是一樣。
我們在上面工程的基礎上看下混編要怎么設置(注意,視情況做出調整):
這里要注意,在添加宏
一定要在前面加一個-D
image.png
方法二:添加Scheme
然后我們可以對不同的
Scheme
配置不同的configuration
來進行環境區分。如下:這樣我們就可以通過切換不同的
Scheme
來切換不同的開發環境。
-
舉個例子,不同的
Scheme
對應不同的AppIcon
:
首先我們要在Assets.xcassets
再添加一個AppIcon
:
image.png
接著我們可以在target
的Build Settings
里面設置不同的configuration
對應不同的AppIcon
:
image.png -
我們還可以針對不同
Scheme
設置不同的App Name
:
在Target
的Build Settings
里面添加自定義的字段,如下:
image.png
假設我們現在就將字段名定義為BUNDLEDISPLAY_NAME
,然后Debug
模式下就叫Debug
,Release
模式下就叫Release
。
接著我們要在Info.plist
文件中替換Bundle name
:
image.png
效果如下:
debug.png
缺點:此時同樣的,我們還是需要在
Target
里面修改很多東西,這樣的還難免會遺漏一些東西,改起來也不是特別的方便。
方法三:利用xcconfig
文件,結合自定義的Scheme
來配置多環境開發
- 首先我們來了解一下什么是
xcconfig
文件,我們在使用cocopod
的時候,會自動什么pod
的xcconfig
文件,如下:
image.png
其實這個xcconfig
文件類似于plist
文件,就是一個Key-Value的集合,其對應的就是Target
中的設置:
image.png - 既然
cocopod
可以定義自己的xcconfig
文件,那么我們也可以定義自己的xcconfig
文件,這樣做的好處是,將需要修改的環境變量集中到一個文件里面,這樣便于管理。
下面我們自定義自己的xcconfig
文件:
image.png - ?? 注意:
xcconfig
文件的命名規則是:<文件夾名稱-APP名稱.對應的configuration>如下:
image.png - 然后我們在
PROJECT
-Info
-Configurations
里面,將不同的configuration
設置對應的xcconfig
文件:
image.png -
xcconfig
文件其實就是一個Key-Value
文件,對應的就是Target
的設置。下面我們來測試一下:
1、首先我們在Target
的Build Settings
里面設置自己的字段:
image.png
2、接著我們給工程加一個test1_Debug
的Scheme
,對應的就是Debug
模式;原來的test1
對應Release
模式:
image.png
3、根據上面講的,將不同的configuration
設置對應的xcconfig
文件,在xcconfig
文件中我們這樣寫:
Debug
文件:APP_CONFIG = APP_Debug_Replace
Release
文件:APP_CONFIG = APP_Release_Replace
4、我們在Info.plist
文件中添加一個剛剛設置的字段:
image.png
5、打印我們自定義的字段:
NSString *path = [NSBundle.mainBundle pathForResource:@"Info" ofType:@"plist"];
NSDictionary *infoDic = [[NSDictionary alloc] initWithContentsOfFile:path];
NSLog(@"%@",infoDic[@"APP_CONFIG"]);
/*運行test1*/
輸出結果:APP_Release_Replace
/*運行test1_Debug*/
輸出結果:APP_Debug_Replace
講到這里,大家可能會覺得第三種方法中,單獨添加一個test1_Debug
完全就是多余,可以通過運行的時候切換test1
的configuration
也能實現上面的效果。
這里請大家考慮一下,實際的開發中,你面對的可能不只是Debug & Release
環境,可能有本地
、測試服
、正式服
等等。因此個人建議,用不同的Scheme
區分開,是比較高效的處理方式。
這里給大家推薦一個網站,可以查到Target
的各個字段對應的縮寫:Xcode Build Settings
- 下面我們介紹一下最后一個知識點:xcconfig文件沖突
- 沖突 1:
實際開發中,我們會使用Cocopods
來管理我們的第三方庫,Cocopods
也會給我們生成一些xcconfig
文件(這里注意?? :每次pod
,Cocopods
都會從新生成xcconfig
文件,所以不要在Cocopods
生成的xcconfig
文件中做修改)
那么這個時候,就有一個問題,我們針對configuration
到底要選哪一個xcconfig
文件呢?
答案當然是我們自定義的xcconfig
這樣有衍生出另一問題,那么pod
生成的xcconfig
我們該怎么處理,如果不添加,則pod install
就會出問題,如果是之前pod
好的工程,那么pod
中針對Target
的一些設置又該怎么辦?
其實很簡單,我們只需要在自定義xcconfig
文件中引入pod
生成的xcconfig
文件就可以了,如下:
#include "Pods/Target Support Files/Pods-test1/Pods-test1.debug.xcconfig"
- 沖突 2:
解決了上面的問題,我們來看另一問題,嚴格將問題2也是一個衍生問題。
如果自定義xcconfig
和 pod
生成的xcconfig
文件,對同一個字段進行了修改,那Xcode會用哪個文件中的配置呢?
答案是:自定義xcconfig
,其實大家想一下就明白了,自定義的 引用 pod
生成的,然后Xcode再引用自定義的。
那么像這種問題我們該怎么解決呢?
這里我們先給出答案:使用$(inherited)
,可以理解為繼承。
下面我們看一下具體的使用場景:
首先我們在自定義的xcconfig
文件中添加
OTHER_LDFLAGS = -framework "SDWebImage"
同時我們也pod
了AFNetworking
。
此時我們會發現,在Target
的Build Settings
-Other Link Flags
路面只有SDWebImage
,如下:
這也就意味著,我們引入的第三方庫的鏈接是失敗的。
這時候,我們就可以在等號加上
-framework "SDWebImage"
:
OTHER_LDFLAGS = $(inherited) -framework "SDWebImage"
這里跟大家分享一下:問題 2 的解決辦法,其實就在pod
自己生成的xcconfig
里面,如果有興趣可以先不自定義xcconfig
,使用pod
引入一個三方庫,看看pod
自動生成的xcconfig
是怎么寫的,然后對應的Target
里面的設置又有了哪些變化。
Tips:
大家在配置自己的xcconfig
文件的時候有幾個小技巧跟大家講一下:
- 1、在
Build Settings
里面自定義了URL
字段,在xcconfig
如何配置//
的問題
如果我們直接在xcconfig
文件中寫上對應的URL
會是被識別為注釋符號
我們可以先定義一個/
的變量:
A = /
HOST_URL = ${A}/192.168.1.1
其中${A}
和 $(A)
是等價的。
- 2、比如說我們現在要配置
OTHER_LDFLAGS
,按照上面講的我們是這樣寫的:
OTHER_LDFLAGS = -framework "SDWebImage"
其實我們還可以添加附加條件,比如:指定特定的開發環境、機型、架構等等,如下:
OTHER_LDFLAGS[config=Debug][sdk=iphonesimulator*][arch=x86_64] = -framework "SDWebImage"
此時OTHER_LDFLAGS
引入SDWebImage
只會在Debug
模式下,運行模擬器
并且對應的執行架構為x86_64
的時候,才會執行。
優先級(由高到低):
- 手動配置Target Build Settings
- Target中配置的xcconfig文件
- 手動配置Project Build Settings
- Project中配置的xcconfig文件