切换项目环境是日常操作之一,如何做到优雅而自动化一直是一个问题,以我们项目为例,以往的方式是通过宏定义的方式,切换时手动切换变量,然后这种做法既不优雅又容易因为手动的原因出现一些问题,比如线上debug(手动狗头)这种操作。当然还有其他的一些方案比如多Tagrget + 宏定义,这种做法的问题是添加文件时需要包含进多个target,不然就会报错,除了资源文件一些代码文件比如Catagory如果没有添加编译期不能发现但到运行时就会Crash。本文介绍一种方式,使用多Configurations + Scheme+User-defined setting来配置和管理项目环境。
先来介绍一下这几个部分
Configurations
image.png如图,选择Project工程,会看到在Info栏有一个Configurations字段,默认情况下,项目会生成两种配置Debug和Release,开发时运行代码使用 Debug 配置,打包一般使用 Release配置,基于这两种配置我们可以做到的是基于当前环境(debug还是release)来设置baseUrl,比如这样
var baseURL: URL {
if Debug {
return testURL
} else {
return productionURL
}
}
然而我们的日常开发中可能会操作的情况有这么四种
- 开发时debug配置,测试环境
- 开发时debug配置,正式环境
- 测试分发Release配置,测试环境
- AppStore/测试分发Release,正式环境
很显然仅仅是Debug和Release这两种环境配置已经满足不了我们的需求,我们需要做的就是新增这两种环境配置。
image.png如图,新增了ProductionDebug和InhouseRelease分别对应开发时正式环境和分发时测试环境。这样我们的项目就有了四种对应的环境配置,基于这些环境配置,我们只需要让我们的操作(Run/Archive)基于不同环境,然后不同的环境内返回不同的baseURL就可以了。那么如何来自做呢。
Scheme
首先我们项目默认只有一个Scheme,相应的Run和Archive操作也默认对应了Debug和Release环境,如下图所示。
image.png
我们新增两种环境后,首先想到的就是新增一个Scheme配置,然后将新增的Scheme的Run和Archive操作对应到我们新增的两种环境即可。如下图所示,我们新增了一个Scheme,然后修改了其Run/Archive操作到对应的ProductionDebug和InhouseRelease环境。这样我们就可以通过两个Scheme来进行四种环境的操作了。
image.pngUser-defined setting
第一步解决了,那么如何配置不同环境的URL呢?
一种比较简单的方式是通过环境代码判断
var baseURL: URL {
var urlString = "baseURL"
#if DEBUG
urlString = "debug url string"
#elseif ProductionDebug
urlString = "production debug url string"
#elseif InhouseRelease
urlString = "release url string"
#else
urlString = "release url string"
#endif
return URL(string: urlString)!
}
一种更好的方式是通过User-defined setting将URL的配置写入其中。选中当前Target,在Build Settings栏点击+号,选择 Add-user-defined setting。
如图所示,我们新增了一个名为BASE_URL的字段,然后在不同的环境下配置了相应的URL,如何使用到这个BASE_URL呢,方法是在infoPlist中新增一个字段
image.png如图,新增一个API_BASE_URL字段,其value引用了Build Settings中的BASE_URL字段。这样在不同环境下就可以引用到相应的URL。
最后在用的地方加载infoPlist中的这个字段就可以了(这里使用了单例+懒加载是为了只加载一次,因为baseURL会频繁调用)。
struct EnvironmentManager {
static var share = KYXEnvironmentManager()
lazy var baseURL: URL = {
let urlString = Bundle.main.infoDictionary?["API_BASE_URL"] as? String ?? ""
return URL(string: urlString)!
}()
}
网友评论