[譯] 輕鬆管理 Swift 項目中的不一樣環境

想象一下,你已經完成了應用程序的開發和測試,如今你已準備好將其提交併發佈。但有個問題:你全部的 API key、URL、圖標或其餘設置都是針對測試環境進行配置的。所以,在提交應用程序以前,你必須將全部這些內容切換到生產環境。顯然,這聽起來就不太好。此外,你可能會在你龐大的應用中忘記一兩個更改,你所提供的服務天然將沒法正常工做。前端

與其使用這種混亂的方法,不如設置幾個環境,並在須要時簡單地更改它們。今天,咱們將最經常使用的幾個方法來嘗試管理環境配置:android

  1. 使用註釋。
  2. 使用全局變量或枚舉。
  3. 使用 target 配置和 scheme 並結合全局標誌。
  4. 使用 target 配置和 scheme 並結合多個 *.plist 文件。

1. 使用註釋

當你有兩個不一樣的環境時,應用程序須要知道它應該鏈接到哪一個環境。想象一下,你有 ProductionDevelopmentStaging 環境和多個 API 端點。處理這個問題的最快速和簡單的方法是使用 3 個不一樣的變量,並註釋掉其中的 2 個:ios

// MARK: - Development
let APIEndpointURL = "http://mysite.com/dev/api"
let analyticsKey = "jsldjcldjkcs"

// MARK: - Production
// let APIEndpointURL = "http://mysite.com/prod/api"
// let analyticsKey = "sdcsdcsdcdc"
// MARK: - Staging
// let APIEndpointURL = "http://mysite.com/staging/api"
// let analyticsKey = "lkjllnlnlk"
複製代碼

這種方法很髒亂,會讓你哭得很厲害。有時我在黑客馬拉松上用它,那對代碼的質量沒有任何要求,只看重速度和靈活性。在任何其餘狀況下,我強烈建議不要使用它。git

2.使用全局變量或枚舉

另外一種流行的方法是有一個全局變量或 Enum(這個會更好)來處理不一樣的配置。你須要在你的 Enum 中聲明 3 個環境(例如在 AppDelegate 文件中)設置它的值:github

enum Environment {
    case development
    case staging 
    case production
}
 
let environment: Environment = .development
 
switch environment {
case .development:
    // 將 web 服務 URL 設置爲開發環境
    // 將 API key 設置爲開發環境
    print("It's for development")
case .staging:
    // 將 web 服務 URL 設置爲預上線環境
    // 將 API key 設置爲開發環境
    print("It's for staging")
case .production:
    // 將 web 服務 URL 設置爲生產環境
    // 將 API key 設置爲開發環境
    print("It's for production")
}
複製代碼

這種方法讓你每次要更改代碼時只需設置一次環境。與之前的方法相比,這個更好,更快並且可讀性更強,但也有不少限制。首先,在運行任何環境時,你始終擁有相同的 Bundle ID。這意味着你沒法同時在設備上擁有 2 個分別對應不一樣環境的應用,這簡直讓人難受。web

此外,爲每一個環境設置不一樣的圖標也是一個不錯的主意,但採用這種方法,你沒法更改圖標。並且,若是你在發佈應用程序以前忘記更改這個全局變量,那你確定會遇到問題。swift


讓咱們繼續嘗試另外兩種方法來更快地切換環境。這兩個方法對於新建的項目和現有的大型項目都適用。因此跟着本教程,你能夠很容易地應用在你現有的一個項目上。後端

應用這些方法以後,你的應用的每一個環境將會使用相同的代碼庫,但對於每種配置,可以擁有不一樣的圖標和不一樣的 Bundle ID。分發過程也很是簡單。而最重要的是,項目經理和測試人員將可以將你不一樣環境配置的應用獨立安裝在他們的設備上,因此他們會徹底理解他們試用的版本。api

3.使用 target 配置和 scheme 並結合全局標誌

在這種方法中,咱們須要建立 3 個不一樣的 configuration 和 3 種不一樣的 scheme,並將 scheme 和對應 configuration 鏈接起來。我將建立一個叫「Environments」的項目來演示這一過程,你也能夠建立一個新項目或在現有項目中實現。安全

在 Project Navigator 面板中點擊你的項目跳到項目設置。在 target 部分中,右鍵單擊現有 target 並選擇 Dublicate 來複制當前 target。

如今咱們有一個新的 target 和一個叫作「Environments copy」的 scheme。讓咱們重命名爲一個合適的名字。左鍵單擊你的新 target,回車,將其名稱更改成「Environments Dev」。

接下來,點擊「Manage Schemes…」,選擇在上一步中建立的新 scheme,而後按回車,重命名使其與新建立的 target 同名避免混淆。

而後,讓咱們建立一個新的圖標資源,以便測試人員和管理員方便地知道他們啓動的 app 對應的配置。

進入 Assets.xcassets,點擊「+」並選擇「New iOS App Icon」。將其名稱更改成「AppIcon-Dev」。

如今咱們能夠將這個新的圖標資源與咱們的開發環境對應起來。進入「Targets」,左鍵單擊你的 Dev taget,找到「App Icon Source」並選擇你的新的圖標資源。

就是這樣,如今每一個 configuration 都有不一樣的圖標。請注意,當咱們建立第二個 configuration 時,第二個 *.plist 文件也是爲咱們的第二個環境生成的。

重要提示:如今咱們有兩種不一樣的方法來處理兩種不一樣的配置:

  1. 爲生產和開發目標添加預處理宏/編譯器標誌。
  2. 將變量添加到 *.plist 中。

咱們將從第一個方法開始講這兩種方法。

添加一個表明開發環境的標誌,首先須要選擇剛纔創建的開發環境的 target,進入「Build Settings」並找到「Swift Compiler — Custom Flags」部分。將該值設置爲「-DDEVELOPMENT」,將你的目標標記爲開發環境。

而後在代碼中像這樣配置不一樣的環境:

#if DEVELOPMENT
let SERVER_URL = "http://dev.server.com/api/"
let API_TOKEN = "asfasdadasdass"
#else
let SERVER_URL = "http://prod.server.com/api/"
let API_TOKEN = "fgbfkbkgbmkgbm"
#endif
複製代碼

如今,若是您選擇 Dev scheme 並運行你的程序,應用程序將會自動運在開發環境配置下。

4.使用 target 配置和 scheme 並結合多個 *.plist 文件

在這種方法中,咱們須要重複上一個方法的前幾個步驟,建立和上個方法相同的幾種 configuration 和 scheme。而後,咱們不須要再添加全局標誌,而是須要添加必要的值到咱們的 .plist 文件中。另外,咱們將在兩個 *.plist 文件中分別添加一個 String 類型的 serverBaseURL 變量,並填上 URL。如今每一個 *.plist 文件都包含一個 URL,咱們須要從代碼中調用它。我認爲,爲咱們的 Bundle 建立一個 extension 將是一個不錯的主意,以下所示:

extension Bundle {
    var apiBaseURL: String {
	return object(forInfoDictionaryKey: "serverBaseURL") as? String ?? ""
    }
}

//And call it from the code like this:
let baseURL = Bundle.main.apiBaseURL
複製代碼

就我我的而言,我更喜歡這種方法,由於在你不該該在代碼中檢查你的配置。你只需詢問 Bundle,只用一行代碼,就能夠根據當前配置獲得須要的結果。

在使用多個 target 的時候

  • 請記住,存儲在 *.plist 文件中的數據可能會被讀取,而且可能很是不安全。一種解決方案是,把敏感密鑰放在代碼中,並僅將其鍵名放在 *.plist 文件中。
  • 添加新文件時,請不要忘記選擇兩個 target 以保持你的代碼在兩種配置中同步。
  • 若是你使用了持續集成服務,例如 Travis CIJenkins,請不要忘記爲它們正確地配置。

結論

從一開始就以可讀和靈活的方式將你的 app 分紅不一樣環境老是有用的。即便用最簡單的技術,咱們也能夠避免許多配置中的典型問題,並顯着提升咱們的代碼質量。

今天,咱們簡要地從最簡單的方法介紹了幾種方法,可能還有更多其它的方法來管理配置。我很期待在評論中看見你的方法。

謝謝閱讀 :)


掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章
相關標籤/搜索