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 Settings
Target
中配置的xcconfig
文件- 手动配置
Project Build Settings
Project
中配置的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
配置项