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
配置项
网友评论