1. 本文讲什么
在项目中,经常会出现不同环境,配置信息不同的情况。比如项目会分为 3 种环境: Debug / Adhoc / Release ,每种环境的请求 Host 不同、bundleId不同、 项目名不同。
本文的目的是介绍几种解决这个问题的4种方法:
- 同一项目中配置多种 Target
- 同一个target, 多个schema
- 同一个schema,使用xconfig文件配置
- 使用 json 文件配置多种数据环境
2.Project / Target / schema 区别
workspace 包含多个项目的
- Project : 包含了项目中所有的代码、资源文件、配置信息。
- Target: 是指对指定的代码、资源文件的具体的构建方式。其中代码和资源文件是项目的子集。
- Schema: 对指定的 Target 的环境配置。
3.方式1:配置多种 Target
增加target
改名字,改icon, info.plist
oc:
macro : 在宏里增加配置
swift:other
swift flag :
4.方式2:同一个target, 多个schema,不同的configuration
project里增加一个configuration, 给每种配置增加不同的宏
增加3个不同环境的schema, 指向不同的configuration
这时,不同的schema 是不同的环境
增加自定义的变量:
增加info.plist文件,中加一个key
读取plist 文件
**
5.方式3:使用xconfig文件配置
- 创建xconfig文件
- configurations中设置当前target不同环境的xconfig文件
- xconfig文件内是key-value 格式的代码
- 将xconfig 中的 key 放到info.plist中,再通过读取infoplist 获取自定义的环境的key.来进行业务逻辑的处理
6.方式4:使用 json 文件配置多种数据环境
写一个json 配置文件,写一个设置页面,读取json里的数据,在页面上可以手动选择需要的环境。
7.xconfig 的书写
xconfig 文件设置key 还可以是链接器参数,它是buildSetting的缩写,与buildSetting的缩写的对应关系在这个网站地址里。注意⚠️:有部分变量不能通过xcconfig配置到Build Settings中,例如:配置PRODUCT_BUNDLE_IDENTIFIER不起作用。
1. 优先级(由高到低):
- 手动配置
Target Build Settings Target中配置的xcconfig文件- 手动配置
Project Build Settings Project中配置的xcconfig文件
xcconfig 中可以直接使用#include ``"RunCMD.xcconfig" 引入另一个xcconfig, 再通过配置$(inherited)让当前变量继承变量原有值,这样会使得多个xconfig文件,及buildSetting 均生效,互不冲突。

2. 基础使用
引用变量,
$()和${}两种写法都可以:VALUE=CatTEACHER=$(VALUE)-${VALUE}
注意⚠️:在
Xcode 11.4及以后版本,可以使用default,来指定变量为空时的默认值:
$(BUILD_SETTING_NAME:default=value)
如果有2个反斜线,比如协议,会被认为为注释,需要将一个反斜线单独定义一个key. 再拼接在一起
SLASH=/HOST=https:$(SLASH)/help.apple.com/xcode/#/dev745c5c974
获取可执行文件的地址 ``` // 环境:Debug, AdHoc,Release CONF=$(CONFIGURATION) // 平台:模拟器,真机 PLATFORM=$(EFFECTIVE_PLATFORM_NAME) // 编译的目录 /Users/admin/Library/Developer/Xcode/DerivedData/TestOC-arahleltyhnhpcdxwdwiqnovagkz/Build/Products BULID_PATH=${BUILD_DIR}
PATH=${BULID_PATH}/${PLATFORM}${CONF}/*
<a name="cRdfX"></a>
## 3. 链接库时一些配置:
1.链接多个库
```c
OTHER_LDFLAGS = $(inherited) -framework SDWebImage -framework AFNetworking
条件变量,根据
SDK、Arch和Configration对设置进行条件化,例如:// 指定`Configration`是`Debug` // 指定`SDK`是模拟器,还有iphoneos*、macosx*等 // 指定生效架构为`x86_64` OTHER_LDFLAGS[config=Debug][sdk=iphonesimulator*[arch=x86_64]]= $(inherited) -framework "Cat"设置后,在 buildSetting 中,也能看到这个设置:

地址 ``` // 头文件地址 HEADER_SEARCH_PATHS = $(inherited) “${SRCROOT}/../LGApp/LGApp/Headers”
// 库地址 FRAMEWORK_SEARCH_PATHS = $(inherited) “${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking” “${PODS_CONFIGURATION_BUILD_DIR}/AJZBase” // xx地址 LIBRARY_SEARCH_PATHS = $(inherited) “${PODS_ROOT}/FlutterPod/ios_frameworks”
9.APP 引用库A, 库A引用库B,库A将自己引入的库重新导出。使得上层APP使用方,可以直接使用库B
// 0. 库重导出 OTHER_LDFLAGS = -Xlinker -reexport_framework -Xlinker AFNetworking $(inherited)
// 1.将一个文件内的所有符号重导出 OTHER_LDFLAGS = -XLinker -reexported_symbols_list ${path}
// 2. 起别名,可以将符号重新导出 OTHER_LDFLAGS=$(inherited) -Xlinker -alias -Xlinker _NSLog -Xlinker Cat_NSLog
10. 动态库A引用动态库B,子库B会找不到。设置动态库A的xconfig文件,来指定B的绝对路径
// 动态库B绝对路径 LD_RUNPATH_SEARCH_PATHS = $(inherited) ${PODS_CONFIGURATION_BUILD_DIR}/AFNetworking
11._通过Cocoapods脚本拷贝_
SCRIPT_DIR = ${SRCROOT}/Pods-LGNetworkManagerTests-frameworks.sh
```
other swift flag 设置-D 表示 “设置条件编译标志为true”

