IOS - 多环境配置
前言
一、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中的配置才会生效,如果不设置,只有我们手动设置的才会生效。