最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

iOS開發(fā)xconfig和script腳本使用詳解

 更新時間:2022年09月08日 16:24:40   作者:MambaYong  
這篇文章主要為大家介紹了iOS開發(fā)xconfig和script腳本使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

引言

利用Xcode進(jìn)行開發(fā)時需要進(jìn)行很多build setting的設(shè)置以便能讓項目按照設(shè)置的進(jìn)行編譯,同時有時候需要在編譯時利用script腳本進(jìn)行一些設(shè)置,本文主要介紹xconfig文件和script腳本在Xcode開發(fā)中使用。

Xcode編譯

在使用xconfig時有幾個關(guān)于Xcode的概念是需要理解的,這里我進(jìn)行通俗簡單的說明,同時需要知道Xcode在編譯的過程中具體幫我們做了那幾件事情。

Xcode target

在實際開發(fā)中一個Xcode創(chuàng)建的項目是可以有多個taget的,比如我們創(chuàng)建一個widgetXcode會自動新建一個target對應(yīng)這個widget,也可以自己新建,同一個項目有多個target可以滿足不同的測試場景,比如在前期開發(fā)階段使用一個target,到UAT階段使用另外一個target。一個target對應(yīng)一個product,也就是編譯后安裝到手機(jī)上的項目,target定義了生成的唯一 product, 它將構(gòu)建該product 所需的文件和處理這些文件所需的指令集整合進(jìn) build system 中,這些指令以 build settingbuild 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)包含debugrelease 兩種build settings 當(dāng)然,每一個 target能夠制定其自己的 build settings,且targetbuild settings 會重寫projectbuild settings。

Xcode scheme

一個project可以有多個target,但是當(dāng)前的target只能有一個,scheme就是用來確定當(dāng)前的target的,并制定當(dāng)前的target使用哪種configuration。

新建configuration

打開項目編輯欄選擇上面的progect同時選擇info欄,可以看到Xcode默認(rèn)添加了二個DebugReleaseconfiguration,點(diǎn)擊做下角的+號按鈕選擇復(fù)制Debug或者Release其中一個configuration來新建并命名一個自己想取的名字,我這里命名為Mamba。

Configuration文件的使用

平時手動的在Xcode中進(jìn)行項目的一些build setting設(shè)置還是比較麻煩的,一個是需要在Xcode中進(jìn)行搜索,另外一個是不好管理,例如需要在debug或者release下進(jìn)行不同的設(shè)置的話就比較麻煩。利用Configuration文件來代替手動設(shè)置則更加的方便,直接新建Configuration Setting file類型文件,如下圖所示:

利用Configuration設(shè)置不同的項目名

Configuration文件是可以繼承的,一般先建立一個Common Configuration文件用來作為父類,為此新建一個名為CommonConfiguration文件,并加入如下代碼:

APP_NAME = TestDemo

然后分別新建名為debug,MambareleaseConfiguration文件,并加入如下代碼:

  • debug
#include "Common.xcconfig"
APP_NAME = $(inherited)Debug
  • Mamba
#include "Common.xcconfig"
APP_NAME = $(inherited)Mamba
  • release
```Swift
#include "Common.xcconfig"
APP_NAME = $(inherited)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)多了一個上文我們添加的名為MambaConfiguration。

點(diǎn)擊左邊的小三角箭頭展開每個Configuration后可以設(shè)置項目的project級別的Configuration Filetarget級別的Configuration File,當(dāng)然也可以默認(rèn)不設(shè)置。分別設(shè)置三個Configuration下的project級別的Configuration FileBase,target級別的Configuration File則為對應(yīng)的Configuration File,如下圖所示:

查看是否設(shè)置成功

點(diǎn)擊TARGETS導(dǎo)航欄,選擇Build Settings并選中AllLevels滑到最下面可看見APP_NAME的值設(shè)置如下:

這里需要解釋一下幾個設(shè)置的級別:

  • Resolved: 最后生效的值
  • Target: 顯示在Target級別生效的值,Target級別的優(yōu)先級是高于Project的,并且默認(rèn)繼承Project設(shè)置的值。
  • Project: 顯示在Project級別生效的值,往常在XcodeGeneral設(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.plistBundle display name的值為 $(APP_NAME)。

測試是否生效

Scheme頁面分別選擇debug,releasemamba三中不同的Configuration環(huán)境運(yùn)行APP成功的根據(jù)不同的Configtation設(shè)置不同的項目運(yùn)行名字。

利用xconfig文件實現(xiàn)OC條件編譯

在開發(fā)中經(jīng)常需要進(jìn)行條件編譯,在OC中可以利用pch文件配合宏來實現(xiàn),例如如下:

#ifdef DEBUG
#define BaseURL @"192.168.1.1:8080/appname/api"
#define PublicKEY @"QWE3R23WR09WURI220WR3TTY5ET3CR2X"
#else
#define BaseURL @"http://api.appname.com"
#define PublicKEY @"32GDG4575UB5M97O7M2X32RFH53QWT43"
#endif

通過在pch文件中利用條件編譯定義不用的宏來實現(xiàn)項目的動態(tài)切換配置,上述宏定義一般定義在.pch中,通常.pch文件中定義的宏都比較雜亂,希望能單獨(dú)放在一個獨(dú)立的文件中,可以通過新建一個頭文件env.h, 把上述宏定義放到env.h中,在需要使用的時候?qū)腩^文件即可,把環(huán)境參數(shù)單獨(dú)放在一個獨(dú)立的頭文件中,更加簡潔,職能更加專一,也便于維護(hù)但是這種做法還不是最好的,因為還需要手動導(dǎo)入頭文件,而且生產(chǎn)環(huán)境參數(shù)和開發(fā)環(huán)境參數(shù)是放在同一個文件中而是不是獨(dú)立分開的,要想獨(dú)立分開并且使用時又不用導(dǎo)入頭文件可以通過Xcode中的Configurations Setting Fil(.xcconfig)來解決,這應(yīng)該是最優(yōu)的實現(xiàn)方式。

xconfig文件的設(shè)置

在上面的Debug.xconfigMamba.xconfig文件中分別加入如下代碼:

  • Debug.xconfig
WEBSERVICE_URL = @"www.baidu.com"
  • Mamba.xconfig
WEBSERVICE_URL = @"www.jd.com"

這樣只是自定義了一個Build Setting變量,不能代碼里像使用宏那樣使用,Xcode是支持利用GCC_PREPROCESSOR_DEFINITIONS在定義宏的,在Common.xconfig文件中加入如下代碼:

GCC_PREPROCESSOR_DEFINITIONS = $(inherited) WEBSERVICE_URL='$(WEBSERVICE_URL)'

TARGET導(dǎo)航欄中Preprocessor Macros即可看見我們定義的宏。

代碼使用

可以在代碼中直接使用定義的宏,當(dāng)切換Configuration時則會根據(jù).xconfig文件輸入不同的打印。

- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"-----------%@-------------",WEBSERVICE_URL);
}

使用#include語法來包含其他配置文件,如#include "Common.xcconfig", 最好是放在文件的最后面,放在文件的開頭也可以。Common.xconfig中第一個鍵的配置必須有:GCC_PREPROCESSOR_DEFINITIONS = $(inherited),沒有Xcode會報錯,暴露自定義鍵時的語法:宏名='$(key)',在代碼或其他地方使用宏名來引用,'$(key)':通過key來指定每個模式下的對應(yīng)的自定義鍵的名字,通常將宏的名字和key的名字保持一致, 注意 等號前后一定不能有空,Common.xconfig中第一個keyGCC_PREPROCESSOR_DEFINITIONS = $(inherited) 后面跟自定義的key,注意在第一個key后面跟上自己定義的key的時候一定不要回車換行,敲一個空格,然后在同一行后面追加就行了,換行會編譯錯誤, 不能換行,不能換行,不能換行!

Swift中條件編譯的實現(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的類用來解析:

import Foundation
enum Config {
  static func stringValue(forKey key: String) -> String {
    guard let value = Bundle.main.object(forInfoDictionaryKey: key) as? String else {
      fatalError("Invalid value or undefined key")
    }
    return value
  }
}

代碼使用

import UIKit
class ViewController: UIViewController {
    override func viewDidLoad() {
        super.viewDidLoad()
        print(Config.stringValue(forKey:"WEBSERVICE_URL"))
    }
}

相比較于OC版本的是不能直接定義宏,需要通過在info.plist定義后并通過方法取出值后才能使用,稍微麻煩了一點(diǎn)。

script的使用

上文我們已經(jīng)知道xconfig文件的使用,其實在編譯之前不只是變量的自定義或者獲取項目的一些默認(rèn)參數(shù),還可以在獲取這些參數(shù)的基礎(chǔ)上,將這些參數(shù)作為script腳本的變量來做一些更有意義的事情,Xcode是支持在編譯之前鏈接script腳本的。

script的初步認(rèn)識

腳本一般來說就是可執(zhí)行的二進(jìn)制文件,下面先制作一個簡單的腳本加深認(rèn)知(實例代碼采用Swift),首先新建一個名為HelloXcode.swift文件,加入如下代碼:

import Foundation
@main
enum MyScript {
  static func main() {
    print("Hello Xcode")
  }
}

下面我們用終端來編譯上面的HelloXcode.swift文件,cd到文件所在的目錄執(zhí)行以下代碼:

xcrun --sdk macosx swiftc -parse-as-library HelloXcode.swift -o CompiledScript

利用macOS SDK來編譯HelloXcode.swift并輸出名為CompiledScript的二進(jìn)制腳本文件,此時可以直接在當(dāng)前目錄利用./CompiledScript執(zhí)行該腳本文件,會直接輸出打印HelloXcode。為了在Xcode編譯階段就能運(yùn)行腳本,我們需要將腳本插入到XcodeBuild Phases中,首先我們先新建一個Build Phases如下所示:

Xcode中的Build Phases選項卡是Xcode build項目的中心,Xcode在編譯項目時其實幫我們做了如下幾件事情:

  • 確定項目的一些依賴并編譯
  • 編譯項目的代碼
  • 鏈接上面編譯的依賴文件
  • 復(fù)制資源文件例如圖片等到項目bundle中

這里我們是要在項目編譯開始之前就運(yùn)行腳本,所以需要調(diào)整新增加的Build Phases的順序,直接拖到Denpencies下面,如下圖所示:


點(diǎn)擊剛剛新加的Build Phases可以重命名,展開后加入如下代碼:


下面的Input Files可以理解為腳本的變量,這里將HelloXcode.swift相對工程文件所在的路$SCRIPT_INPUT_FILE_0進(jìn)行引用,$(SRCROOT)代表工程文件所在的目錄,運(yùn)行項目在build log(不是打印臺)會看見如下輸出:

script的實際運(yùn)用

利用script來實現(xiàn)每當(dāng)build的時候改變 Info.plistBundle version或者Bundle version string (short)的值,新建一個IncBuildNumber.swift 文件,加入如下代碼:

import Foundation
@main
enum IncBuildNumber {
  static func main() {
    guard let infoFile = ProcessInfo.processInfo
      .environment["INFOPLIST_FILE"]
    else {
      return
    }
    guard let projectDir = ProcessInfo.processInfo.environment["SRCROOT"] else {
      return
    }
    if var dict = NSDictionary(contentsOfFile:
      projectDir + "/" + infoFile) as? [String: Any] {
      guard 
        let currentVersionString = dict["CFBundleShortVersionString"]
          as? String,
        let currentBuildNumberString = dict["CFBundleVersion"] as? String,
        let currentBuildNumber = Int(currentBuildNumberString)
      else {
        return
        }
      dict["CFBundleVersion"] = "\(currentBuildNumber + 1)"
      if ProcessInfo.processInfo.environment["CONFIGURATION"] == "Release" {
        var versionComponents = currentVersionString
          .components(separatedBy: ".")
        let lastComponent = (Int(versionComponents.last ?? "1") ?? 1)
        versionComponents[versionComponents.endIndex - 1] = 
          "\(lastComponent + 1)"
        dict["CFBundleShortVersionString"] = versionComponents
          .joined(separator: ".")
      }
      (dict as NSDictionary).write(
        toFile: projectDir + "/" + infoFile, 
        atomically: true)
    }
  }
}

當(dāng)Xcode在執(zhí)行run script phase時會通過環(huán)境變量environment variables來共享build settings,可以將環(huán)境變量在這里理解為全局變量,這里通過環(huán)境變量拿到了info.plist中的CFBundleShortVersionStringCFBundleVersion變量,并根據(jù)CONFIGURATION配置的是Release還是Debug來修改對應(yīng)的BundleVersion,至此每當(dāng)build時都會改變相應(yīng)的BuildVersion值。

總結(jié)

本文主要介紹了利用xconfig文件如何進(jìn)行項目的動態(tài)配置,并進(jìn)行了實際的演示,同時介紹了scriptXcode中編譯的基本使用,并配合xconfig文件能讓Xcode在編譯前做更多有意義的事情,更多關(guān)于iOS使用xconfig script腳本的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • iOS開發(fā)之圖片模糊效果的五種實現(xiàn)代碼

    iOS開發(fā)之圖片模糊效果的五種實現(xiàn)代碼

    本篇文章主要介紹了iOS開發(fā)之模糊效果的五種實現(xiàn)代碼。本文針對這五種方式講解一下具體的實現(xiàn),有興趣的同學(xué)可以一起來了解一下
    2017-04-04
  • 詳解iOS應(yīng)用開發(fā)中的ARC內(nèi)存管理方式

    詳解iOS應(yīng)用開發(fā)中的ARC內(nèi)存管理方式

    這篇文章主要介紹了詳解iOS應(yīng)用開發(fā)中的ARC內(nèi)存管理方式,文中示例基于Objective-C語言,需要的朋友可以參考下
    2016-02-02
  • IOS 打包靜態(tài)庫詳細(xì)介紹

    IOS 打包靜態(tài)庫詳細(xì)介紹

    這篇文章主要介紹了IOS 打包靜態(tài)庫詳細(xì)介紹的相關(guān)資料,這里對打包靜態(tài)庫做了詳細(xì)的說明,并進(jìn)行了總結(jié),需要的朋友可以參考下
    2016-11-11
  • iOS監(jiān)控筆記之啟動crash

    iOS監(jiān)控筆記之啟動crash

    iOS崩潰是讓iOS開發(fā)人員比較頭痛的事情,app崩潰了,說明代碼寫的有問題,下面這篇文章主要給大家介紹了關(guān)于iOS監(jiān)控筆記之啟動crash的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2018-05-05
  • IOS 數(shù)據(jù)存儲詳解及實例代碼

    IOS 數(shù)據(jù)存儲詳解及實例代碼

    這篇文章主要介紹了IOS 數(shù)據(jù)存儲詳解及實例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • iOS中實現(xiàn)簡單易懂秒殺倒計時/倒計時代碼

    iOS中實現(xiàn)簡單易懂秒殺倒計時/倒計時代碼

    這篇文章主要介紹了iOS中實現(xiàn)簡單易懂秒殺倒計時/倒計時代碼,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2017-02-02
  • Objective-C實現(xiàn)無限循環(huán)輪播器

    Objective-C實現(xiàn)無限循環(huán)輪播器

    這篇文章主要介紹了Objective-C實現(xiàn)無限循環(huán)輪播器的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-05-05
  • Objective-C中利用正則去除非數(shù)字字母漢字方法實例

    Objective-C中利用正則去除非數(shù)字字母漢字方法實例

    正則表達(dá)式對我們?nèi)粘i_發(fā)來說是必不可少的,下面這篇文章主要給大家介紹了關(guān)于Objective-C中如何利用正則去除非數(shù)字字母漢字的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2018-06-06
  • iOS 截取字符串中兩個指定字符串中間的字符串方法

    iOS 截取字符串中兩個指定字符串中間的字符串方法

    下面小編就為大家分享一篇iOS 截取字符串中兩個指定字符串中間的字符串方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-03-03
  • ios原生二維碼掃描與生成的實現(xiàn)教程

    ios原生二維碼掃描與生成的實現(xiàn)教程

    這篇文章主要給大家介紹了關(guān)于ios原生二維碼掃描與生成的相關(guān)資料,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-09-09

最新評論

秦安县| 内江市| 绥中县| 长垣县| 女性| 武山县| 吉隆县| 色达县| 长岛县| 新乡市| 紫金县| 丰都县| 从江县| 宁强县| 黔西县| 洛隆县| 揭西县| 会东县| 含山县| 固镇县| 九龙坡区| 宁明县| 冷水江市| 陆川县| 获嘉县| 临城县| 凌云县| 澳门| 嵊州市| 吉安县| 资源县| 阿勒泰市| 双流县| 克什克腾旗| 同仁县| 麻城市| 万全县| 西畴县| 柳河县| 贺州市| 宜城市|