1. 本文讲什么

在项目中,经常会出现不同环境,配置信息不同的情况。比如项目会分为 3 种环境: Debug / Adhoc / Release ,每种环境的请求 Host 不同、bundleId不同、 项目名不同。
本文的目的是介绍几种解决这个问题的4种方法:

  1. 同一项目中配置多种 Target
  2. 同一个target, 多个schema
  3. 同一个schema,使用xconfig文件配置
  4. 使用 json 文件配置多种数据环境

**

2.Project / Target / schema 区别

workspace 包含多个项目的

  • Project : 包含了项目中所有的代码、资源文件、配置信息。
  • Target: 是指对指定的代码、资源文件的具体的构建方式。其中代码和资源文件是项目的子集。
  • Schema: 对指定的 Target 的环境配置。

3.方式1:配置多种 Target

增加target
改名字,改icon, info.plist
oc:
macro : 在宏里增加配置

swift:other
swift flag :

缺点:
多 info文件
配置繁琐

4.方式2:同一个target, 多个schema,不同的configuration

project里增加一个configuration, 给每种配置增加不同的宏
增加3个不同环境的schema, 指向不同的configuration
这时,不同的schema 是不同的环境
增加自定义的变量:
image.png
增加info.plist文件,中加一个key
读取plist 文件
**

5.方式3:使用xconfig文件配置

  1. 创建xconfig文件
  2. configurations中设置当前target不同环境的xconfig文件
  3. xconfig文件内是key-value 格式的代码
  4. 将xconfig 中的 key 放到info.plist中,再通过读取infoplist 获取自定义的环境的key.来进行业务逻辑的处理

    6.方式4:使用 json 文件配置多种数据环境

    写一个json 配置文件,写一个设置页面,读取json里的数据,在页面上可以手动选择需要的环境。

7.xconfig 的书写

xconfig 文件设置key 还可以是链接器参数,它是buildSetting的缩写,与buildSetting的缩写的对应关系在这个网站地址里。注意⚠️:有部分变量不能通过xcconfig配置到Build Settings中,例如:配置PRODUCT_BUNDLE_IDENTIFIER不起作用。

1. 优先级(由高到低):

  1. 手动配置Target Build Settings
  2. Target中配置的xcconfig文件
  3. 手动配置Project Build Settings
  4. Project中配置的xcconfig文件

xcconfig 中可以直接使用#include ``"RunCMD.xcconfig" 引入另一个xcconfig, 再通过配置$(inherited)让当前变量继承变量原有值,这样会使得多个xconfig文件,及buildSetting 均生效,互不冲突。

image.png

2. 基础使用

  1. 引用变量,$()${}两种写法都可以:

    1. VALUE=Cat
    2. TEACHER=$(VALUE)-${VALUE}
  2. 注意⚠️:在Xcode 11.4及以后版本,可以使用default,来指定变量为空时的默认值:

  1. $(BUILD_SETTING_NAME:default=value)
  1. 如果有2个反斜线,比如协议,会被认为为注释,需要将一个反斜线单独定义一个key. 再拼接在一起

    1. SLASH=/
    2. HOST=https:$(SLASH)/help.apple.com/xcode/#/dev745c5c974
  2. 获取可执行文件的地址 ``` // 环境: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
  1. 条件变量,根据SDKArchConfigration对设置进行条件化,例如:

    // 指定`Configration`是`Debug`
    // 指定`SDK`是模拟器,还有iphoneos*、macosx*等
    // 指定生效架构为`x86_64`
    OTHER_LDFLAGS[config=Debug][sdk=iphonesimulator*[arch=x86_64]]= $(inherited) -framework "Cat"
    

    设置后,在 buildSetting 中,也能看到这个设置:
    image.png

  2. 地址 ``` // 头文件地址 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 ``` image.png

other swift flag 设置-D 表示 “设置条件编译标志为true”

image.png