RainedAllNight‘s Blog

使用Configurations-+-Scheme-+-User-defined-setting管理你的项目环境

字数统计: 1k阅读时长: 3 min
2019/04/24 Share

切换项目环境是日常操作之一,如何做到优雅而自动化一直是一个问题,以我们项目为例,以往的方式是通过宏定义的方式,切换时手动切换变量,然后这种做法既不优雅又容易因为手动的原因出现一些问题,比如线上debug(手动狗头)这种操作。当然还有其他的一些方案比如多Tagrget + 宏定义,这种做法的问题是添加文件时需要包含进多个target,不然就会报错,除了资源文件一些代码文件比如Catagory如果没有添加编译期不能发现但到运行时就会Crash。本文介绍一种方式,使用多Configurations + Scheme+User-defined setting来配置和管理项目环境。

先来介绍一下这几个部分

Configurations

image.png

如图,选择Project工程,会看到在Info栏有一个Configurations字段,默认情况下,项目会生成两种配置DebugRelease,开发时运行代码使用 Debug 配置,打包一般使用 Release配置,基于这两种配置我们可以做到的是基于当前环境(debug还是release)来设置baseUrl,比如这样

1
2
3
4
5
6
7
var baseURL: URL {
if Debug {
return testURL
} else {
return productionURL
}
}

然而我们的日常开发中可能会操作的情况有这么四种

  • 开发时debug配置,测试环境
  • 开发时debug配置,正式环境
  • 测试分发Release配置,测试环境
  • AppStore/测试分发Release,正式环境

很显然仅仅是Debug和Release这两种环境配置已经满足不了我们的需求,我们需要做的就是新增这两种环境配置。

image.png

如图,新增了ProductionDebugInhouseRelease分别对应开发时正式环境和分发时测试环境。这样我们的项目就有了四种对应的环境配置,基于这些环境配置,我们只需要让我们的操作(Run/Archive)基于不同环境,然后不同的环境内返回不同的baseURL就可以了。那么如何来自做呢。

Scheme

首先我们项目默认只有一个Scheme,相应的Run和Archive操作也默认对应了Debug和Release环境,如下图所示。
image.png

我们新增两种环境后,首先想到的就是新增一个Scheme配置,然后将新增的Scheme的Run和Archive操作对应到我们新增的两种环境即可。如下图所示,我们新增了一个Scheme,然后修改了其Run/Archive操作到对应的ProductionDebug和InhouseRelease环境。这样我们就可以通过两个Scheme来进行四种环境的操作了。

image.png

User-defined setting

第一步解决了,那么如何配置不同环境的URL呢?

一种比较简单的方式是通过环境代码判断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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。
屏幕快照 2019-04-24 上午11.45.22.png

image.png

如图所示,我们新增了一个名为BASE_URL的字段,然后在不同的环境下配置了相应的URL,如何使用到这个BASE_URL呢,方法是在infoPlist中新增一个字段

image.png

如图,新增一个API_BASE_URL字段,其value引用了Build Settings中的BASE_URL字段。这样在不同环境下就可以引用到相应的URL。
最后在用的地方加载infoPlist中的这个字段就可以了(这里使用了单例+懒加载是为了只加载一次,因为baseURL会频繁调用)。

1
2
3
4
5
6
7
8
struct EnvironmentManager {
static var share = KYXEnvironmentManager()

lazy var baseURL: URL = {
let urlString = Bundle.main.infoDictionary?["API_BASE_URL"] as? String ?? ""
return URL(string: urlString)!
}()
}

最后,当你要切换时只需要选择相应的Scheme来操作就可以了。
当然更好的一种方式是结合fastlane,可以让整个过程更加自动化,具体的下篇来聊
CATALOG
  1. 1. Configurations
  2. 2. Scheme
  3. 3. User-defined setting
    1. 3.0.0.1. 最后,当你要切换时只需要选择相应的Scheme来操作就可以了。
    2. 3.0.0.2. 当然更好的一种方式是结合fastlane,可以让整个过程更加自动化,具体的下篇来聊