利用xcconfig文件完成多环境配置

优质
小牛编辑
132浏览
2023-12-01

利用xcconfig文件完成多环境配置

xcconfig本质上是一个key-value配置文件
xcconfig文件命名建议: 所在目录-Project名称.环境 (参考CocoaPods)
xcode build settings环境参数缩写查询资料: xcodebuildsettings

一、xcconfig文件的创建和配置导入

  1. 新建xcconfig文件, 保证项目结构清晰, 单独新建目录管理xcconfig配置文件

    新建xcconfig文件

  2. Project - Configurations下, 为不同的Configurations选择不同的xcconfig文件

    设置xcconfig

这里xcconfig文件的创建和导入配置就完成了
同时通过截图可以看到, 有两层入口, 可以直接配置Project, 也可以针对Target进行配置导入


二、结合多环境hosts的配置, 利用xcconfig实现

  • 分别在上面新建的xcconfig文件下新增以下内容, 用来模拟网络请求的域名

    • Config-MultiEnvByXCConfig.Release.xcconfig
      HOST_URL = 127.0.0.1

    • Config-MultiEnvByXCConfig.Debug.xcconfig
      HOST_URL = 127.0.0.2

      注意Value前后不要添加" 如果是域名, //会被识别为注释, 解决方案是提前声明一个/的变量

      SLASH=/
      HOST_URL = http:${SLASH}/127.0.0.1
      

      {}和()等价

  • Info.plist中添加xcconfig内的环境变量

    增加环境变量到info.plist中

  • 代码中使用

      NSString *hostURL = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"HOST_URL"];
      self.describeLabel.text = hostURL;
    

这样就完成了xcconfig多环境的简单配置

但是这样简单的操作下来, 调试时仍然不够方便, 如果需要验证多环境, 起码目前是需要在Edit Scheme中切换Debug/Release

可以结合Scheme为不同的Configurations设置不同的Scheme, 每次编译不同环境, 直接切换Scheme, 而不是一个Scheme修改Configurations来切换环境

xcconfig更强大之处是在控制Build settings中的选项, 将零散的配置项汇总到xcconfig配置文件中, 保证一个环境下的配置一目了然的目的


三、xcconfig来设置Build Settings选项

  • Other Linker Flags

    平时配置动态库/静态库会设置Other Linker Flags, 比如现在想要配置AFNetworking, 在Config-MultiEnvByXCConfig.Release.xcconfig文件中增加如下配置

      // ld -> build settings 中的 Other Linker Flags
      OTHER_LDFLAGS = -framework "AFNetworking"
    

    编译Release这个Configurations, 切换到Build Settings下检查Other Linker Flags选项

    ld配置

    刚刚Config-MultiEnvByXCConfig.Release.xcconfig同步生效了, 因为只设置了一个xcconfig文件, 对比Debug中是没有包含的

    并且支持条件参数

      OTHER_LDFLAGS[config=Debug][sdk=iphonesimulator*][arch=x86_64]=-framework "AFNetworking"
    

四、xcconfig冲突

通过上面导入xcconfig配置可见, 导入选项是单选, 只能选择指定某一个xcconfig配置文件

在使用CocoaPods后, 默认提供了DebugReleasexcconfig配置

自定义配置与pod配置

Debug下的配置改为自定义的, 再次执行pod install结束后提示

[!] CocoaPods did not set the base configuration of your project because your project already has a custom config set. In order for CocoaPods integration to work at all, please either set the base configurations of the target `MultiEnvByXCConfigWOConflict` to `Target Support Files/Pods-MultiEnvByXCConfigWOConflict/Pods-MultiEnvByXCConfigWOConflict.debug.xcconfig` or include the `Target Support Files/Pods-MultiEnvByXCConfigWOConflict/Pods-MultiEnvByXCConfigWOConflict.debug.xcconfig` in your build configuration (`MultiEnvByXCConfigWOConflict/Config/Config-MultiEnvByXCConfigWOConflict.Debug.xcconfig`).

由于我们存在自定义配置, 所以CocoaPods并不会强制去覆盖选中的xcconfig

处理方案

  • 在自定义xcconfig中导入CocoaPodsxcconfig
#include "Pods/Target Support Files/Pods-MultiEnvByXCConfigWOConflict/Pods-MultiEnvByXCConfigWOConflict.debug.xcconfig"

注意前面需要补充根目录Pods/

这种处理方案仍然存在问题

两个不同的xcconfig设置相同的KEY, 以目前的场景, 在我自定义的xcconfig#includeCocoaPodsxcconfig, 在Podxcconfig中会设置OTHER_LDFLAGS并导入Podfile中的依赖库, 在我自定义的xcconfig中最后会覆盖掉Podxconfig, 冲突仍然存在

决绝方法

  • 继承 $(inherited)

确保最终的xcconfig配置KEY时使用$(inherited)继承导入的xcconfig配置

OTHER_LDFLAGS = $(inherited) -framework "AFNetworking"

注意谁才是最终在Project-Configurations中的选中的xcconfig

五、优先级(由高到低)

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