App Xcode多環境配置探索

App多環境配置探索

簡介

App開發為什么需要使用多環境呢?原因很簡單,就是為了 App 或 App 新功能 在對所有用戶開放之前能經過充分測試與驗證,將問題降到最低,讓用戶有個好的使用體驗。有了多環境,內部測試將完全與發布的產品獨立開來,互不影響,這就是多環境的好處。

環境配置

App 的環境配置方案有很多種,這里我使用一種個人認為比較好的方式來實現, 即 xcconfigplist 相結合的方式 。通常情況,我們會給 app 配置 3 個服務器,即 Development, Staging, Production。那 App 又如何配置,才能很方便的去連接這 3 個服務器呢?這就是我們今天想要討論的問題。 首先,我們將 App 的運行環境分為三種:

  • Development
    Development 即我們常說的開發環境,開發人員在此環境中開發與自測, 連接 Development 服務器。

  • Staging
    正式產品線上環境前的預演,也就是模擬產品線上環境,連接 Staging 服務器。 QA在 Staging上對新版本做最后一輪測試, 通過后才能發布到產品線上。

  • Production
    最終產品線上環境,連接 Production 服務器,App直接向所有用戶開放。

Debug / Release

iOS App 的工程配置默認包含 DebugRelease 兩種模式,那兩者有什么區別呢?

  • Debug
    Debug 為調試模式,編譯器不會對代碼做最后的優化,包含的程序信息多,非常方便設置斷點進行調試。所以這種模式下打包的 App 體積會比較大。

  • Release
    Release 為發布模式,編譯器最終會對代碼做優化,不包含調試信息,所以打包出來的 App 體積更小,運行速度也越快,但不便于調試。

<font color=red>所以我們在環境配置中提到的 Development, Staging, Production 都會對應 DebugRelease 兩種模式。</font>

配置多環境

具體的步驟我就不寫了,大家應該都知道如何去做,如果不知道如何操作,可以參考這里,你也可以在這里下載完整演示項目Github倉庫

新建 xcconfig 文件

首先,我們新建 3 個工程配置文件, 例如 Development.xcconfig, Staging.xcconfig, Production.xcconfig, 其中的一個配置文件內容如下:

// 因為使用了 Pods, 所以需要將 Pods 生成的配置文件包含進來. 如果不使用 Pods, 可以去去掉這一行。
#include "./Pods/Target Support Files/Pods-AppEnvironment/Pods-AppEnvironment.release-development.xcconfig"
    
APP_NAME = App環境(開發)
APP_BUNDLE_ID = me.evanxlh.environment.development
CONFIGRATION_PLIST_FILENAME = Development
XCConfig Files

新建 Plist 配置文件

然后我們新建 3 個 Plist 配置文件,將需要加的其它配置項用 plist 文件來存儲,方便解析。例如我們創建以下 3 個 文件: Development.plist, Staging.plist, Production.plist, 其中一個配置文件內容如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>serverURL</key>
    <string>http://10.20.22.10</string>
    <key>bugly</key>
    <dict>
        <key>name</key>
        <string>Bugly-Development</string>
        <key>appId</key>
        <string>FAdfakldjfadlf8908o</string>
        <key>appSecret</key>
        <string>HKdfadkdfladfkdfadfa</string>
    </dict>
</dict>
</plist>
Configuration Plists

修改 Info.plist

為了能在程序中從 plist 配置文件中讀到配置項,我們需要在 Info.plist 文件中加入一個 key, 比如命名為: ConfigurationPlistFileName, value 設置為$(CONFIGRATION_PLIST_FILENAME)CONFIGRATION_PLIST_FILENAME由之前新建的 xcconfig 文件定義。這樣我們就可以在 App 中加載 plist 配置文件了。

![Info Plist](https://gitee.com/evanxlh/Resources/raw/master/blog/app-multi-environments/info-plist.png]

配置工程

  • 首先點擊你的工程,如下圖所示。然后在 Configurations下新增配置,<font color=red>記住 Development, Staging, Production 的 Debug 模式都要從 Debug復制出來得到,Development, Staging, Production 的 Release 模式都要從 Release 復制出來得到。</font>
Project Configs Overview
  • Development, Staging, ProductionDebugRelease 模式指定對應的 xcconfig 文件。
    Project Config Details

Plist 配置文件解析

import HandyJSON

struct AppConfiguration {
    
    fileprivate static let shared = AppConfiguration()
    
    /// The `key` in the `Info.plist` which tells the filename of the configuration plist file.
    fileprivate let keyInInfoPlist = "ConfigurationPlistFileName"
    
    fileprivate var values: Values!
    fileprivate var configurationType: ConfigurationType!
    
    private init() {
        let configInfo = loadConfigurationValues()
        self.values = configInfo.0
        self.configurationType = configInfo.1
    }
    
    fileprivate func loadConfigurationValues() -> (Values, ConfigurationType) {
        guard let filename = Bundle.main.infoDictionary?[keyInInfoPlist] as? String else {
            fatalError("Please specify configuration plist filename in Info.plist")
        }
        
        guard let type = ConfigurationType(rawValue: filename) else {
            fatalError("Not supported configuration name")
        }
        
        guard let url = Bundle.main.url(forResource: filename, withExtension: "plist") else {
            fatalError("Configuration plist file not found")
        }
        
        guard let dic = NSDictionary(contentsOf: url) else {
            fatalError("The format of configuration plist file is invalid")
        }
        
        guard let values = Values.deserialize(from: dic) else {
            fatalError("The format of configuration plist file is invalid")
        }
        return (values, type)
    }
    
}

// MARK: - Public APIs

extension AppConfiguration {
    
    enum ConfigurationType: String {
        case development = "Development"
        case staging = "Staging"
        case production = "Production"
    }
    
    struct OpenPlatform: HandyJSON {
        var name: String = ""
        var appId: String = ""
        var appSecret: String = ""
    }
    
    /// All the configuration values
    struct Values: HandyJSON {
        var serverURL: String = ""
        var bugly: OpenPlatform = OpenPlatform()
    }
    
    /// Type of app configuration which is applied.
    static var type: ConfigurationType {
        return shared.configurationType
    }
    
    /// Accessing all the configuration items by this property.
    static var values: Values {
        return shared.values
    }
}

最后我們就可以直接用 AppConfiguration.values 獲取所有的配置項了。

Scheme 創建

首先分為為 Development, Staging, Production 環境配置 創建 Scheme:

Three Schemes

然后為每一個 Scheme 進行配置:

Scheme Config

使用 Pods 注意事項

因為我們自己給工程添加了 xcconfig 文件,所以 pod install 時不會再去設置工程的配置文件。這時需要我們在自己創建的 xcconfig 文件中將 Pod 的 xcconfig 文件引用進來,然后執行以下操作:

  1. <font color=red>刪除 PodsPodfile.lockxcworkspace文件 </font>

  2. <font color=red>重新執行 pod install </font>

結束語

好了,配置完成。

如果一些操作不熟悉,你也可以參考這篇文章:
https://thoughtbot.com/blog/let-s-setup-your-ios-environments

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,739評論 6 534
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,634評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,653評論 0 377
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,063評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,835評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,235評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,315評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,459評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,000評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,819評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,004評論 1 370
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,560評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,257評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,676評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,937評論 1 288
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,717評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,003評論 2 374