App多環境配置探索
簡介
App開發為什么需要使用多環境呢?原因很簡單,就是為了 App 或 App 新功能
在對所有用戶開放之前能經過充分測試與驗證,將問題降到最低,讓用戶有個好的使用體驗。有了多環境,內部測試將完全與發布的產品獨立開來,互不影響,這就是多環境的好處。
環境配置
App 的環境配置方案有很多種,這里我使用一種個人認為比較好的方式來實現, 即 xcconfig
與 plist
相結合的方式 。通常情況,我們會給 app 配置 3 個服務器,即 Development
, Staging
, Production
。那 App 又如何配置,才能很方便的去連接這 3 個服務器呢?這就是我們今天想要討論的問題。 首先,我們將 App 的運行環境分為三種:
Development
Development
即我們常說的開發環境,開發人員在此環境中開發與自測, 連接Development
服務器。Staging
正式產品線上環境前的預演,也就是模擬產品線上環境,連接Staging
服務器。 QA在Staging
上對新版本做最后一輪測試, 通過后才能發布到產品線上。Production
最終產品線上環境,連接Production
服務器,App直接向所有用戶開放。
Debug / Release
iOS App 的工程配置默認包含 Debug
和 Release
兩種模式,那兩者有什么區別呢?
Debug
Debug
為調試模式,編譯器不會對代碼做最后的優化,包含的程序信息多,非常方便設置斷點進行調試。所以這種模式下打包的 App 體積會比較大。Release
Release
為發布模式,編譯器最終會對代碼做優化,不包含調試信息,所以打包出來的 App 體積更小,運行速度也越快,但不便于調試。
<font color=red>所以我們在環境配置
中提到的 Development
, Staging
, Production
都會對應 Debug
和 Release
兩種模式。</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
新建 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>
修改 Info.plist
為了能在程序中從 plist 配置文件中讀到配置項,我們需要在 Info.plist
文件中加入一個 key, 比如命名為: ConfigurationPlistFileName
, value 設置為$(CONFIGRATION_PLIST_FILENAME)
, CONFIGRATION_PLIST_FILENAME
由之前新建的 xcconfig
文件定義。這樣我們就可以在 App 中加載 plist 配置文件了。

/// 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:
然后為每一個 Scheme 進行配置:
使用 Pods 注意事項
因為我們自己給工程添加了 xcconfig
文件,所以 pod install
時不會再去設置工程的配置文件。這時需要我們在自己創建的 xcconfig
文件中將 Pod 的 xcconfig
文件引用進來,然后執行以下操作:
<font color=red>刪除
Pods
、Podfile.lock
、xcworkspace
文件 </font><font color=red>重新執行
pod install
</font>
結束語
好了,配置完成。
如果一些操作不熟悉,你也可以參考這篇文章:
https://thoughtbot.com/blog/let-s-setup-your-ios-environments