前言

一、workspace、project、target、scheme

二 、通过多target配置多环境

三、通过Scheme配置多环境

四、xcconfig

五、xcconfig坑点注意


我们在日常的开发过程中,使用多环境配置是很有必要的。

比如:提测的时候需要发布测试环境的安装包,快要上线了可能会发布预发环境的安装包,上线的时候又要发线上环境的包。

再比如:同一套代码可以根据不同的环境编译出不同的app。

所以很有必要把多环境的配置,系统的总结一下。


一、workspace、project、target、scheme

区别:

1、workspace 工作空间, 可以单独的管理多个项目,可以通过配置,让各个项目相互依赖。
2、project 包含了项目所有的代码,资源文件,所有信息。
3、target 对指定代码和资源文件的具体构建方式。
4、Scheme 对指定target的环境配置

注意:

1、一个project可以有多个target。
2、一个target只能指定同一个project的代码和资源。
3、一个文件或者资源可以被多个target指定。
4、一个target可以有多个Scheme的配置

使用域总结:

1、workspace可以管理多个project
2、一个project可以有多个target
3、一个target可以有多个Scheme的配置

二 、通过多target配置多环境

1、target配置

在demo1的工程下,我多建立一个target叫做demo-dev

然后会生成一个新的info.plist,我将名字改成demo-dev.plist

同时修改build setting中的info.plist File

通过以上操作,新的target就建立出来了。

通过建立多个target,我们就可以把测试、预发、线上环境等,每一个环境建立一个target,然后根据自定义的宏定义进行区分。
OC自定义宏定义:

swift自定义标示

swift 如果要类似oc的宏,需要在other swift flags 中去设置,并且需要加上-D的参数。
那么-D是什么意思呢:通过 swiftc --help | grep -- '-D' 可以看到意思是: 将条件编译标志标记为true,所以需要加上-D这个参数。

2、解决实际问题

在之前的业务开发过程中,有一个第三方的sdk,只给了包含armv7和arm64指令集的静态库,没有提供x86的。此时可以利用添加多个target,解决模拟器无法运行的情况。

3、target总结

通过target可以来区分不同文件的加载以及不同环境的配置。但是对于多环境配置来说,显然是一种比较麻烦的方式。


三、通过Scheme配置多环境

1、首先在PROJECT -> info -> Configurations 添加一个配置,这里添加一个Beta

2、新建Scheme

3、设置Beta对应的Scheme的配置为Beta

4、给每一个环境:Debug、Beta、Release都添加一个sheme。方便切换环境。

四、xcconfig

再第三步的过程中,我们已经配置好了多个Scheme,那么我们需要再通过配置xcconfig来达到真正的多环境配置。

什么是xcconfig?

xcconfig 其实就是xcode里的config文件,本质是一个用来保存Build Settings键值的纯文本文件。
这些键值会覆盖Build Settings中的值,所以当在xcconfig文件中配置了的选项,在Build Settings中设置将失效。但是经过测试,并不会覆盖掉我们手动添加的设置。

我们先针对不同环境创建xcconfig文件。

我们在Project的info中把xcconfig和每一个环境关联上。

此时我们已经配置好了xcconfig的关联。

那么在平时的开发中,我们一般会使用cocoapods来管理第三方的或者私有的库。在我们使用cocoapods时,也会指定它下面的xcconfig文件。这显然会和我们自己定义的xcconfig文件冲突。
其实很简单,只要我们在自己的xcconfig文件中加入:

#include "Pods/Target Support Files/Pods-demo1/Pods-demo1.debug.xcconfig"

这样就可以导入cocoapods的xcconfig文件了。

下面我们做一个demo,将从不同环境下读取BASE_URL。

#include "Pods/Target Support Files/Pods-demo1/Pods-demo1.debug.xcconfig"
BASE_URL = http:/$()/127.0.0.1

我们配置一个BASE_URL,注意这里要完整的http链接的话,需要在//中间加上$(),或者将/用变量区分:

A=/
BASE_URL = http:${A}/127.0.0.1   //这里${} 等价与 $()

我们再切换不同的Scheme之后,会打印对应xcconfig文件中的值。
因为此时在User-Defined中已经有了我们设置的键值了

再比如我配置一下 Other Linker Flags

OTHER_LDFLAGS = -framework "AFNetworking"

同样的会在Build Setting里面生效。
同时,我们可以设置每一个key的条件设置:

OTHER_LDFLAGS[config=Debug][sdk=iphonesimulator*][arch=x86_64] = -framework "AFNetworking"

但是注意:Build Setting中的键值不一定都能在xcconfig中设置,比如 bundle id。

五、xcconfig坑点注意

1、在上面我们设置了Other Linker Flags,但是在xcconfig文件中,我们设置的是OTHER_LDFLAGS,这个其实是Other Linker Flags的缩写,在 Xcode Build Settings,这个链接中,其他设置的缩写都能找到。

2、在xcconfig中的配置,很可能会把原本的设置给覆盖了。

比如在cocoapods文件下,同样设置了 OTHER_LDFLAGS = -framework "AFNetworking",而我在自己的xcconfig文件下也去设置OTHER_LDFLAGS的话,就会产生冲突。
此时我们需要设置一个继承的概念: $(inherited)

OTHER_LDFLAGS = $(inherited) -framework "AFNetworking"

此时就不会有任何冲突了。

3、基于第二步,我继续手动在Build Setting 里面设置other linker flags,此时会不会被覆盖呢?


可以注意到,当我手动添加了xx的时候,Beta对应的设置呈现出高亮的状态,代表此时xcconfig的设置优先级已经小于build setting手动设置的优先级了。所以是不会被覆盖的。
但是这里还要注意一点,就是在build setting中的配置需要设置$(inherited)之后,我们xcconifg中的配置才会生效,如果不设置,只有我们手动设置的才会生效。

总结: 关于多环境的配置,我们可以使用多Scheme+xcconfig来设置。