- 原文地址:Effective Environment Switching in iOS
- 原文做者:Pablo Villar
- 譯文出自:掘金翻譯計劃
- 本文永久連接:github.com/xitu/gold-m…
- 譯者:swants
- 校對者:charsdavy VernonVan
工欲善其事,必先利其器。在 iOS 中,如何處理 配置環境 和根據需求自定義的 設置 關係也尤其重要。雖然 Xcode 提供了一系列的工具幫助咱們進行妥善地配置。但遺憾的是,我見過的不少團隊在絕大多數時候都沒有充分利用這些輔助工具。這並非他們的錯:蘋果只爲咱們提供了一些不怎麼好用的默認配置,而沒有更好的幫助咱們學習如何達到最佳實踐。前端
在這篇文章裏,咱們將探索如何更好地利用 Xcode 配置,如何把 APP 的設置定義得更加有條理。android
Xcode 能夠經過各類配置構建不一樣設置的包。通俗地講,配置就是告訴編譯器如何構建版本的一系列設置。IDE 容許你根據不一樣的配置來自定義一些設置。你可能常常看到這些:ios
等等…git
Debug 和 Release 是 Xcode 提供的兩種默認配置。你徹底也能夠建立你本身的配置,但咱們一般不這麼作,由於自定義的配置是否有效可能取決於項目,iOS 開發者們對哪些配置能夠對項目廣泛有效尚未達成共識。github
這兩種默認配置有幾處差異,具體的差異在這裏我不會詳細討論,只是簡單歸納下:swift
在 debug 構建的版本中,Xcode 會給咱們發送完整的符號調試信息來幫助咱們調試應用,而且 Xcode 不會對代碼進行優化(更快的構建速度)。而在 release 構建的版本中,不會發送調試信息而且代碼會被優化(較慢的構建速度)。後端
至於這兩種配置的用途,debug 一般會在咱們平常開發中使用。而 release 咱們一般會在須要將 APP 分發給其餘非開發人員如:測試人員、項目經理、客戶或用戶時使用。api
須要注意的是,這兩個配置一般是不能徹底知足需求的。並且開發者常常把 ≪debug vs. release≫ 和 ≪staging vs. production≫ 這兩個概念搞混,這徹底是不該該的。xcode
一些項目使用不一樣的配置環境:開發環境、臨時環境、生產環境、預生產環境等等,用你最想用的那個就好。這種分類方式和上面討論的兩種默認配置沒有直接聯繫。就算咱們強制這麼分類,用的時候達到的效果也沒有想象中的那樣好。好比,你想準備構建一個 release 版本,但這並不意味着你的 APP 必定要指向 生產 服務器:想像一下,你須要爲 QA 打個 release 的版本的包,而這個包須要在臨時服務器上進行測試。 這時就連 debug & release 兩個默認的配置也不能知足需求了。bash
所以,我想用能夠知足咱們更多需求的其餘配置方案來代替基本的 debug & release 配置。爲了足夠簡單,在個人方案中只會保留臨時環境和生產環境,在你須要使用其它環境配置時,你會發如今個人方案裏能夠輕鬆添加。
咱們能夠定義四種配置環境:
從它們的名字上,你就能猜到它們大概的設置,下面就是它們的詳細設置:
實現的操做也是很是簡單,找到 project 的 Settings > Info > Configurations,而後點擊 + 按鈕。拷貝一份 Debug 配置,並將默認的配置命名爲 「Debug Staging」,拷貝出來的配置命名爲 「Debug Production」。按照這個方式對 Release 進行處理。
當你操做完後是這個效果:
一個 project 包含四種不一樣的配置環境。
我使用 「 TestFlight」 命名 release 配置,而不是使用原來的 「Release」 命名是有緣由的。由於代碼中有些特定事件只在最終用戶使用時觸發,而在測試人員和客戶使用時不觸發。一個具體的場景就是使用用戶統計來跟蹤事件,這可能要求跟蹤事件僅做用於最終用戶,而不是生產環境下的測試人員。在這種狀況下, 咱們就要考慮 TestFlight Production 配置具備的細微差異,所以咱們須要將這個配置繼續細分下去。引進第五種配置:
你能夠快速地拷貝一份 TestFlight Production 來添加這個配置。但須要注意的是這個配置可能一直不會用到,由於你不必定會遇到須要細分 TestFlight Production 配置的需求。
那麼,如今你可能很想知道 如何根據所選配置來管理 APP 中的觸發事件。這些將會在接下來部分詳細介紹。
有不少方式能夠作到根據所選不一樣配置來執行不一樣的操做:預編譯器指令、環境變量、各類 plist 文件等等。這些方式都有本身的優缺點,這裏只討論我將採起的比較純淨的方式。
須要根據配置執行的各類操做一般能夠由變量來控制,經過這些變量來決定 APP 的行爲。這些變量一般稱爲 settings 。好比一些像這樣的 settings :服務器 API 的 base URL、Facebook App ID、日誌的詳細級別、是否支持離線訪問等等。
接着,展現我如今如何根據所選配置來管理這些自定義 settings 的方法。從個人以往經驗來看,這是目前最方便的方案。
APP 的自定義 settings 能夠經過單例很簡單的獲取到。
struct Settings {
static var shared = Settings()
let apiURL: URL
let isOfflineAccessEnabled: Bool
let feedItemsPerPage: Int
private init() {
let path = Bundle.main.path(forResource: "Info", ofType: "plist")!
let plist = NSDictionary(contentsOfFile: path) as! [AnyHashable: Any]
let settings = plist["AppSetings"] as! [AnyHashable: Any]
apiURL = URL(string: (settings["ServerBaseURL"] as! String))!
isOfflineAccessEnabled = settings["EnableOfflineAccess"] as! Bool
feedItemsPerPage = settings["FeedItemsPerPage"] as! Int
print("Settings loaded: \(self)")
}
}
複製代碼
這個結構體用來讀取和記錄 APP 的各類 settings(這些 settings 會在 APP 的 Info.plist
文件中定義),這樣咱們就能夠在代碼中隨時拿到這些 settings。在這裏我喜歡使用強制解包,由於這樣若是缺乏某項設置,APP 也會沒法運行。
在 Info.plist
文件中定義 appSettings 。這裏我建議你們使用字典把這些設置彙總到一塊兒。
這樣,咱們就很是純淨地完成了對 APP settings 的讀取。這些 settings 在不一樣的配置環境中值都是不一樣的,還差一點就完成了。
想一下,在全部的工程內 什麼會隨配置的不一樣而改變 ? 對,編譯器的代碼優化級別、header 的搜索路徑、描述文件等等。若是咱們可以定義咱們本身的隨所選配置改變的設置,那不就簡單了!事實證實,咱們確實能夠建立用戶自定義的設置。
建立 User-Defined settings 很是簡單,只須要在你的 Target > Build Settings 中,點擊 + 按鈕,而後選擇 「Create User-Defined Setting」。這些也能夠在 project > Build Settings 下建立,但我以爲在 Target > Build Settings 建立更合適。
由於你剛建立的 User-Defined Settings 可能還需與其餘的 Settings 來搭配使用,因此建議最好用合適的前綴來命名。
我這裏使用了我名字縮寫來做爲 User-Defined Settings 的前綴, 但我建議最好用項目名的縮寫。
接下來,在你的 Info.plist
文件中引用對應的屬性值,你能夠這樣作:
$(YOUR_USER_DEFINED_SETTING_NAME)
複製代碼
真正神奇的地方在於:你能夠將 Info.plist
中 settings 的全部已經填好的屬性值替換爲 User-Defined Setting 的對應地址。而你現有的自定義 setting 各需對應一條 User-Defined Setting。
當 Info.plist
文件被編譯時,它會獲取所選配置對應的全部 settings 屬性值,而這些屬性值也會在編譯時對應到每一個 settings 上。
如今,你就能夠在你的代碼裏隨時隨地 優雅 地獲取到這些 settings 的屬性值:
if Settings.shared.isOfflineAccessEnabled {
// do stuff
}
複製代碼
最後,在 Xcode 中選擇所需的編譯配置就很是簡單了:
或者在 CLI 中:
採用這套方案,咱們會得到這些好處:
然而,這個方案也有些值得警戒的地方:
.xcodeproj
中修改這些設置的值,而不能在外部 靈活 修改這些設置的值。雖然這些隱患能夠一一排除,可是,這個方案的初衷只是爲了從這片幾乎空白的領域摸索出這些工具更好的使用方法。解決這些問題就意味着更多更復雜的修改,並且這些已經超出了本文討論的內容,我不但願這篇文章跑題。但相信我,咱們作的已經足夠完善了。在下篇文章裏,咱們將研究如何處理這些隱患,並讓咱們的項目變得更加完善...
待續。
掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。