Xcode中的常见名词:
-
Project:包含了项目所有的代码,资源文件,所有信息。 -
Target:对指定代码和资源文件的具体构建方式。 -
Scheme:对指定Target的环境配置。
日常开发中,对于不同环境,例如
Debug、Release,项目中的环境变量可能存在差异,此时如何高效的进行多环境配置呢?
方式一:
通过Target进行多环境配置
找到
TARGETS,复制一个新的Target
项目中对于新
Target,对应生成一个新的info.plist
对新
Target和info.plist重命名
对
info.plist改名后,还需要在LoginApp-Dev的Build Settings里,找到Packaging的Info.plist File配置项,同步修改info.plist的命名
此时我们可以对两个
Target进行不同的配置,例如在LoginApp-Dev的Build Settings里,设置宏DEV=1
在
LoginApp的Build Settings里,设置宏DEV=0
代码中使用
#if DEV条件限制,执行不同Target会触发不同的代码分支
运行项目时,可以选择不同
Target下的Schemes
不同
Target下的Schemes运行后,设备上会产生多个App
使用多
Target的缺陷:
- 生成多个
info.plist- 对
Build Settings手动配置过于繁琐
方式二:
通过Scheme进行多环境配置
找到
PROJECT,添加一个新的Configurations
将新创建的
Configuration命名为Beta
此时在
LoginApp的Build Settings里,很多配置项都多了Beta的独立设置
选择
Edit Scheme...
在
Bulid Configuration里,也增加了Beta模式的选项。在这里切换不同的Bulid Configuration运行,可以让各自环境的配置生效
当然这样的操作过于繁琐,我们可以针对不同环境,添加各自的
Scheme
选择
Target,指定Name
这里新建两个
Scheme,分别命名为Beta和Debug
选择
Edit Scheme...,此时右上角的Scheme可以切换,将各自的Scheme选择对应的Bulid Configuration
例如:
Beta的Bulid Configuration选择为Beta
Debug的Bulid Configuration选择为Debug
LoginApp的Bulid Configuration选择为Release
运行项目时,可以直接切换
Schemes,比之前方便了很多
案例:
日常开发中,例如请求服务端接口,在不同环境下域名可能是不一样的,我们可以针对不同
Schemes进行不同域名的配置来到
Bulid Settings,点击+,选择Add User-Defined Setting
添加
Host_Url,对应不同Schemes配置不同的域名
在
Info.plist里,暴露Host_Url供项目使用
代码中,添加读取
Info.plist的相关代码
选择
Beta运行项目,此时打印Host_Url为http//:127.0.0.1
不同编译环境的
Schemes运行后,设备上会产生多个App
xconfig文件
使用多Scheme方式可以解决多个info.plist的问题,但是在Bulid Settings中的手动配置并没有改善。这里推荐使用xconfig文件,它可以针对Bulid Settings中的配置项进行统一管理。
xconfig文件并不是Shell脚本,它类似配置文件,Xcode会以KeyValue的方式进行读取。
宏定义
项目内创建
Config目录
在
Config目录下创建xconfig文件
分别创建
Debug和Release环境下的xconfig,命名方式建议项目名.环境.xcconfig
打开
LoginApp.Debug.xcconfig,写入APP_CONFIG=Debug
打开
LoginApp.Release.xcconfig,写入APP_CONFIG=Release
选择
PROJECT,针对不同环境配置对应的xcconfig。可以针对Project,也可以针对Target
这里我们针对
Target进行配置
在
Info.plist里,暴露APP_CONFIG供项目使用
代码中,添加读取
Info.plist的相关代码
当前项目以
Debug模式运行,此时打印APP_CONFIG为Debug
打开
Bulid Settings找到User-Defined配置项,可以看到它自动加上了APP_CONFIG节点
管理Bulid Settings配置项
日常开发中,当我们要链接静态库或动态库时,需要对
Bulid Settings的Other Linker Flags进行配置,这时可以使用xcconfig统一管理
打开
LoginApp.Debug.xcconfig,写入OTHER_LDFLAGS = -framework "AFNetworking",其中OTHER_LDFLAGS代表的就是Other Linker Flags配置项
项目以
Debug模式编译后,打开Bulid Settings找到Other Linker Flags,在xconfig文件内的配置已经生效
如何找到Bulid Settings配置项在xcconfig中的命名?
在
Bulid Settings中存在众多配置项,它们在xcconfig中的命名应该是什么?可以通过 xcodebuildsettings 网站进行查看例如:对
Bulid Settings中的Header Search Paths进行配置
打开网站,搜索
header search paths
在搜索结果中,可以找到
Header Search Paths配置项在xcconfig中的命名
打开
LoginApp.Debug.xcconfig,写入HEADER_SEARCH_PATHS = /use/info/inclue(路径随意写的)
项目以
Debug模式编译后,打开Bulid Settings找到Header Search Paths,在xconfig文件内的配置已经生效
xcconfig文件的冲突
项目中使用
CocoaPods导入第三方类库,这里导入AFNetworking和SDWebImage两个类库
此时Pods也会自动生成xcconfig文件
Pods生成的xcconfig文件内容
自定义
xcconfig文件内容
此时问题来了,每种
Configuration指定的xcconfig文件只能有一个
如果使用
Pods生成的xcconfig文件,自定义的配置项无法生效。而使用自定义xcconfig文件,编译又报错
这种场景使用
include关键字,将Pods生成的xcconfig文件导入到自定义xcconfig文件内。此时指定自定义xcconfig文件,可以正常编译使用
另一个问题,当多个
xcconfig文件存在相同配置项,例如HEADER_SEARCH_PATHS,此时只有后面的配置项可以生效。打开Bulid Settings的Header Search Paths配置项,里只有自定义xcconfig文件内的/use/info/inclue
解决方式:使用
$(inherited)关键字,继承相同配置项
打开
Bulid Settings,此时Header Search Paths配置项,合并了Pods和自定义的xcconfig内容
使用
xcconfig文件,同时也可以在Bulid Settings手动配置,配置项之间可以并存
在
Bulid Settings手动配置,并不会影响到xcconfig文件的内容
对于
Bulid Settings配置项的优先级
- 手动配置
Target Build SettingsTarget中配置的xcconfig文件- 手动配置
Project Build SettingsProject中配置的xcconfig文件
注释
xcconfig文件只有一种注释方式//
引入文件
在创建
xcconfig文件的时候,可以根据需求,创建多个。也就意味着,可以通过include关键字导入其他的xcconfig内的配置#include "Debug.xcconfig"
include引入文件时,如果是以/开头,代表绝对路径#include "/Users/zang/Zang/Spark/LoginApp/Pods/Target Support Files/Pods-LoginApp/Pods-LoginApp.debug.xcconfig"
include引入文件时,也可以使用相对路径#include "Pods/Target Support Files/Pods-LoginApp/Pods-LoginApp.debug.xcconfig"
变量定义
按照
OC命名规则,仅由大写字母,数字和下划线组成。原则上大写,也可以自由发挥。字符串可以是",也可以是'相同配置项,使用
$(inherited)关键字继承OTHER_LDFLAGS = -framework SDWebImage OTHER_LDFLAGS = $(inherited) -framework AFNetworking等同于将两行配置项的值连起来写
OTHER_LDFLAGS = -framework SDWebImage -framework AFNetworking引用变量,使用
$()和${}两种写法都可以VALUE=Cat TEACHER=$(VALUE)-${VALUE}
URL变量中存在//SLASH =/ HOST_URL = http:${SLASH}/192.168.1.100
- 将
/定义为SLASH变量- 在
HOST_URL中使用${SLASH},避免直接使用//变为注释
条件变量
根据
config、sdk和arch对设置进行条件化OTHER_LDFLAGS[config=Debug][sdk=iphonesimulator*[arch=x86_64]= $(inherited) -framework "Cat"
- 指定
config是Debug- 指定
sdk是模拟器,还有iphoneos*、macosx*等- 指定
arch生效架构为x86_64在
Xcode 11.4及以后版本,可以使用default,来指定变量为空时的默认值$(BUILD_SETTING_NAME:default=value)
通过多Target进行代码管理
多Target可以对参与编译的代码文件和资源文件进行各自管理, 并且多Target之间不会相互干扰
选择一个
Target,选择Build Phases
在
Compile Sources中,可以对参与编译的代码文件进行添加或删除操作
在
Copy Bundele Resources中,同样可以对资源文件进行添加或删除操作
Swift宏定义
在
Build Settings里,设置Other Swift Flags配置项
- 与
OC的差异是,需要在自定义宏前面增加-D参数打开终端,使用
swiftc --help | grep -- "-D"命令,查看-D参数
-D:添加自定义标记设置为true
总结:
- 多
Target可以控制需要编译的文件 - 多
Scheme提供了多套环境变量 - 使用
xconfig文件可以更好的管理Bulid Settings配置项
































































