這篇文章主要為大家介紹了iOS開發(fā)xconfig和script腳本使用詳解,有需要的朋友可以借鑒參考下。
目錄
引言
Xcode編譯
Xcode target
Xcode project
Xcode scheme
新建configuration
Configuration文件的使用
利用Configuration設(shè)置不同的項(xiàng)目名
設(shè)置Configuration
查看是否設(shè)置成功
設(shè)置Info.plist
測試是否生效
利用xconfig文件實(shí)現(xiàn)OC條件編譯
xconfig文件的設(shè)置
Swift中條件編譯的實(shí)現(xiàn)
script的使用
script的初步認(rèn)識
script的實(shí)際運(yùn)用
總結(jié)
引言
利用Xcode
進(jìn)行開發(fā)時需要進(jìn)行很多build setting
的設(shè)置以便能讓項(xiàng)目按照設(shè)置的進(jìn)行編譯,同時有時候需要在編譯時利用script
腳本進(jìn)行一些設(shè)置,本文主要介紹xconfig
文件和script
腳本在Xcode
開發(fā)中使用。
Xcode編譯
在使用xconfig
時有幾個關(guān)于Xcode
的概念是需要理解的,這里我進(jìn)行通俗簡單的說明,同時需要知道Xcode
在編譯的過程中具體幫我們做了那幾件事情。
Xcode target
在實(shí)際開發(fā)中一個Xcode
創(chuàng)建的項(xiàng)目是可以有多個taget
的,比如我們創(chuàng)建一個widget
時Xcode
會自動新建一個target
對應(yīng)這個widget
,也可以自己新建,同一個項(xiàng)目有多個target
可以滿足不同的測試場景,比如在前期開發(fā)階段使用一個target
,到UAT
階段使用另外一個target
。一個target
對應(yīng)一個product
,也就是編譯后安裝到手機(jī)上的項(xiàng)目,target
定義了生成的唯一 product
, 它將構(gòu)建該product
所需的文件和處理這些文件所需的指令集整合進(jìn) build system
中,這些指令以 build setting
和 build phases
的形式存在,我們用xconfig
文件來設(shè)置 build setting
,同時將script
腳本添加到build phases
中。
新建target
Xcode project
Xcode project
是一個倉庫,該倉庫包含了所有的文件,資源和用于生成一個或者多個software products
的信息,它包含一個或者多個targets
,其中的每一個 target
指明了如何生成 products
。project
為其擁有的所有 targets
定義了默認(rèn)的build settings
,例如project
中默認(rèn)包含debug
和release
兩種build settings
當(dāng)然,每一個 target
能夠制定其自己的 build settings
,且target
的build settings
會重寫project
的 build settings
。
Xcode scheme
一個project
可以有多個target
,但是當(dāng)前的target
只能有一個,scheme
就是用來確定當(dāng)前的target
的,并制定當(dāng)前的target
使用哪種configuration
。
新建configuration
打開項(xiàng)目編輯欄選擇上面的progect
同時選擇info
欄,可以看到Xcode
默認(rèn)添加了二個Debug
和Release
的configuration
,點(diǎn)擊做下角的+
號按鈕選擇復(fù)制Debug
或者Release
其中一個configuration
來新建并命名一個自己想取的名字,我這里命名為Mamba
。
Configuration文件的使用
平時手動的在Xcode
中進(jìn)行項(xiàng)目的一些build setting
設(shè)置還是比較麻煩的,一個是需要在Xcode
中進(jìn)行搜索,另外一個是不好管理,例如需要在debug
或者release
下進(jìn)行不同的設(shè)置的話就比較麻煩。利用Configuration
文件來代替手動設(shè)置則更加的方便,直接新建Configuration Setting file
類型文件,如下圖所示:
利用Configuration設(shè)置不同的項(xiàng)目名
Configuration
文件是可以繼承的,一般先建立一個Common Configuration
文件用來作為父類,為此新建一個名為Common
的Configuration
文件,并加入如下代碼:
然后分別新建名為debug
,Mamba
和release
的Configuration
文件,并加入如下代碼:
debug
Mamba
release
上面利用#include
進(jìn)行導(dǎo)入依賴的Configuration
文件,并利用$(inherited)
來引用依賴的Configuration
文件中的變量。
Configuration
文件中的語法一般是SETTING_NAME = VALUE
,具體等式二邊設(shè)置的值可見蘋果官網(wǎng).
設(shè)置Configuration
點(diǎn)擊PROJECT
導(dǎo)航欄并選擇Info
會發(fā)現(xiàn)多了一個上文我們添加的名為Mamba
的Configuration
。
點(diǎn)擊左邊的小三角箭頭展開每個Configuration
后可以設(shè)置項(xiàng)目的project
級別的Configuration File
和target
級別的Configuration File
,當(dāng)然也可以默認(rèn)不設(shè)置。分別設(shè)置三個Configuration
下的project
級別的Configuration File
為Base
,target
級別的Configuration File
則為對應(yīng)的Configuration File
,如下圖所示:
查看是否設(shè)置成功
點(diǎn)擊TARGETS
導(dǎo)航欄,選擇Build Settings
并選中All
和Levels
滑到最下面可看見APP_NAME
的值設(shè)置如下:
這里需要解釋一下幾個設(shè)置的級別:
Resolved
: 最后生效的值Target
: 顯示在Target
級別生效的值,Target
級別的優(yōu)先級是高于Project
的,并且默認(rèn)繼承Project
設(shè)置的值。Project
: 顯示在Project
級別生效的值,往常在Xcode
的General
設(shè)置的值就是這一級別的。iOS Default
: 顯示iOS
默認(rèn)設(shè)置的值。
加上Configuration File
后優(yōu)先級順序從低到高如下:
Platform defaults
Project.xcconfig file
Project file build settings
Target .xcconfig file
Target build settings
設(shè)置Info.plist
最后為了通過Configuration File
來控制APP
運(yùn)行時名字的顯示,需要在Info.plist
中鏈接Bundle display name
屬性(沒有的話需要新增)到我們上面設(shè)置的user-defined setting(APP_NAME)
上,為此修改Info.plist
中Bundle display name
的值為 $(APP_NAME)
。
測試是否生效
在Scheme
頁面分別選擇debug
,release
和mamba
三中不同的Configuration
環(huán)境運(yùn)行APP
成功的根據(jù)不同的Configtation
設(shè)置不同的項(xiàng)目運(yùn)行名字。
利用xconfig文件實(shí)現(xiàn)OC條件編譯
在開發(fā)中經(jīng)常需要進(jìn)行條件編譯,在OC
中可以利用pch
文件配合宏來實(shí)現(xiàn),例如如下:
通過在pch
文件中利用條件編譯定義不用的宏來實(shí)現(xiàn)項(xiàng)目的動態(tài)切換配置,上述宏定義一般定義在.pch
中,通常.pch
文件中定義的宏都比較雜亂,希望能單獨(dú)放在一個獨(dú)立的文件中,可以通過新建一個頭文件env.h
, 把上述宏定義放到env.h
中,在需要使用的時候?qū)腩^文件即可,把環(huán)境參數(shù)單獨(dú)放在一個獨(dú)立的頭文件中,更加簡潔,職能更加專一,也便于維護(hù)但是這種做法還不是最好的,因?yàn)檫€需要手動導(dǎo)入頭文件,而且生產(chǎn)環(huán)境參數(shù)和開發(fā)環(huán)境參數(shù)是放在同一個文件中而是不是獨(dú)立分開的,要想獨(dú)立分開并且使用時又不用導(dǎo)入頭文件可以通過Xcode
中的Configurations Setting Fil(.xcconfig)
來解決,這應(yīng)該是最優(yōu)的實(shí)現(xiàn)方式。
xconfig文件的設(shè)置
在上面的Debug.xconfig
和Mamba.xconfig
文件中分別加入如下代碼:
Debug.xconfig
Mamba.xconfig
這樣只是自定義了一個Build Setting
變量,不能代碼里像使用宏那樣使用,Xcode
是支持利用GCC_PREPROCESSOR_DEFINITIONS
在定義宏的,在Common.xconfig
文件中加入如下代碼:
在TARGET
導(dǎo)航欄中Preprocessor Macros
即可看見我們定義的宏。
代碼使用
可以在代碼中直接使用定義的宏,當(dāng)切換Configuration
時則會根據(jù).xconfig
文件輸入不同的打印。
使用#include
語法來包含其他配置文件,如#include "Common.xcconfig"
, 最好是放在文件的最后面,放在文件的開頭也可以。Common.xconfig
中第一個鍵的配置必須有:GCC_PREPROCESSOR_DEFINITIONS = $(inherited)
,沒有Xcode
會報(bào)錯,暴露自定義鍵時的語法:宏名='$(key)'
,在代碼或其他地方使用宏名來引用,'$(key)'
:通過key
來指定每個模式下的對應(yīng)的自定義鍵的名字,通常將宏的名字和key
的名字保持一致, 注意 等號前后一定不能有空,Common.xconfig
中第一個key
是GCC_PREPROCESSOR_DEFINITIONS = $(inherited)
后面跟自定義的key
,注意在第一個key
后面跟上自己定義的key
的時候一定不要回車換行,敲一個空格,然后在同一行后面追加就行了,換行會編譯錯誤, 不能換行,不能換行,不能換行!
Swift中條件編譯的實(shí)現(xiàn)
在Swift
中是不支持通過GCC_PREPROCESSOR_DEFINITIONS
來定義宏的,但是可以通過定義Custom Flags
進(jìn)行定義,這里介紹另外一種方法,還是通過.xconfig文件
進(jìn)行獲取我們需要的宏。前面我們通過info.plist
獲取到了.xconfig
文件中自定義的變量,再次我們同樣通過info.plist
來獲取自定義的變量的值來當(dāng)做宏使用,首先在info.plist
中新建一個WEBSERVICE_URL
變量,并設(shè)置值為'$(WEBSERVICE_URL)'
,由于需要解析info.plist
中的變量,再次封裝一個config.swift
的類用來解析:
代碼使用
相比較于OC
版本的是不能直接定義宏,需要通過在info.plist
定義后并通過方法取出值后才能使用,稍微麻煩了一點(diǎn)。
script的使用
上文我們已經(jīng)知道xconfig
文件的使用,其實(shí)在編譯之前不只是變量的自定義或者獲取項(xiàng)目的一些默認(rèn)參數(shù),還可以在獲取這些參數(shù)的基礎(chǔ)上,將這些參數(shù)作為script
腳本的變量來做一些更有意義的事情,Xcode
是支持在編譯之前鏈接script
腳本的。
script的初步認(rèn)識
腳本一般來說就是可執(zhí)行的二進(jìn)制文件,下面先制作一個簡單的腳本加深認(rèn)知(實(shí)例代碼采用Swift
),首先新建一個名為HelloXcode.swift
文件,加入如下代碼:
下面我們用終端來編譯上面的HelloXcode.swift
文件,cd
到文件所在的目錄執(zhí)行以下代碼:
Bash
利用macOS SDK
來編譯HelloXcode.swift
并輸出名為CompiledScript
的二進(jìn)制腳本文件,此時可以直接在當(dāng)前目錄利用./CompiledScript
執(zhí)行該腳本文件,會直接輸出打印HelloXcode
。為了在Xcode
編譯階段就能運(yùn)行腳本,我們需要將腳本插入到Xcode
的Build Phases
中,首先我們先新建一個Build Phases
如下所示:
Xcode
中的Build Phases
選項(xiàng)卡是Xcode build
項(xiàng)目的中心,Xcode
在編譯項(xiàng)目時其實(shí)幫我們做了如下幾件事情:
確定項(xiàng)目的一些依賴并編譯
編譯項(xiàng)目的代碼
鏈接上面編譯的依賴文件
復(fù)制資源文件例如圖片等到項(xiàng)目bundle中
這里我們是要在項(xiàng)目編譯開始之前就運(yùn)行腳本,所以需要調(diào)整新增加的Build Phases
的順序,直接拖到Denpencies
下面,如下圖所示:
點(diǎn)擊剛剛新加的Build Phases
可以重命名,展開后加入如下代碼:
下面的Input Files
可以理解為腳本的變量,這里將HelloXcode.swift
相對工程文件所在的路$SCRIPT_INPUT_FILE_0
進(jìn)行引用,$(SRCROOT)
代表工程文件所在的目錄,運(yùn)行項(xiàng)目在build log
(不是打印臺)會看見如下輸出:
script的實(shí)際運(yùn)用
利用script
來實(shí)現(xiàn)每當(dāng)build的時候改變 Info.plist
中Bundle version
或者Bundle version string (short)
的值,新建一個IncBuildNumber.swift
文件,加入如下代碼:
當(dāng)Xcode
在執(zhí)行run script phase
時會通過環(huán)境變量environment variables
來共享build settings
,可以將環(huán)境變量在這里理解為全局變量,這里通過環(huán)境變量拿到了info.plist
中的CFBundleShortVersionString
和CFBundleVersion
變量,并根據(jù)CONFIGURATION
配置的是Release
還是Debug
來修改對應(yīng)的BundleVersion
,至此每當(dāng)build時
都會改變相應(yīng)的BuildVersion
值。
總結(jié)
本文主要介紹了利用xconfig
文件如何進(jìn)行項(xiàng)目的動態(tài)配置,并進(jìn)行了實(shí)際的演示,同時介紹了script
在Xcode
中編譯的基本使用,并配合xconfig
文件能讓Xcode
在編譯前做更多有意義的事情
請立即點(diǎn)擊咨詢我們或撥打咨詢熱線: 134 3935 8888,我們會詳細(xì)為你一一解答你心中的疑難。項(xiàng)目經(jīng)理在線