需求
- 在App开发中经常有一些环境参数随着环境(开发环境、演练环境(测试环境)、生产环境)的不同而配置不同,例如接口的基本地址baseURL,加密使用的密钥等,以接口的基本地址为例:可能在开发环境中直接使用内网地址配置“http://192.168.1.1:8080/appname/api“, 在生产环境(发布环境)使用域名配置”http://api.appname.com“, 这些值应该如何更优雅的配置呢?最不推荐的做法是在预编译头文件.pch中定义两个宏定义,如下
#define BaseURL @"192.168.1.1:8080/appname/api"
// #define BaseURL @"http://api.appname.com"
开发的时候将生产的配置注释掉,在发布的时候把测试的配置注释掉,来回切换,这样也能达到目的,但是这种做法有一个不能容忍的缺点是要手动切换配置,项目中一般会有多个这样的环境参数,假如在发布的时候忘记切换,后果自己想吧,等着哭吧。。。
- 为了解决手动切换环境参数可以通过Debug模式判断来定义,这样在App发布的时候就不用做任何切换就能动态的切换配置,再也不用手动切换环境参数了!,代码如下
#ifdef DEBUG
#define BaseURL @"192.168.1.1:8080/appname/api"
#define PublicKEY @"QWE3R23WR09WURI220WR3TTY5ET3CR2X"
#else
#define BaseURL @"http://api.appname.com"
#define PublicKEY @"32GDG4575UB5M97O7M2X32RFH53QWT43"
#endif
- 上述宏定义一般定义在.pch中,通常.pch文件中定义的宏都比较杂乱,希望能单独放在一个独立的文件中,可以通过新建一个头文件env.h, 把上述宏定义放到env.h中,在需要使用的时候导入头文件即可,把环境参数单独放在一个独立的头文件中,更加简洁,职能更加专一,也便于维护但是这种做法还不是最好的,因为还需要手动导入头文件,而且生产环境参数和开发环境参数是放在同一个文件中而是不是独立分开的,要想独立分开并且使用时又不用导入头文件可以通过Xcode中的Configurations Setting Fil(.xcconfig)来解决,这应该是最优的实现方式。
最优解决方案
Xcode中可以创建.xcconfig配置文本,该配置文件Xcode会根据当前模式是Debug模式还是Release模式自动选择对应的配置文件去加载,我们在项目中或其他地方就像使用在.pch文件中定义的宏那样来直接使用.xcconfig配置文件中定义的常量值
具体操作步骤
1、 创建三个Configuration Settings File文件,该文件的后缀为.xcconfig, 三个文件的命名分别命名为Common.xcconfig, Debug.xcconfig, Release.xcconfig, Debug.xcconfig和Release.xcconfig可以使用#include来包含Common.xcconfig配置文件, 注意在创建.xcconfig的时候Xcode默认是不会选中Targets的,注意要选中!
2、 分别在Debug.xcconfig、Release.xcconfig中定义键值对,在Common.xcconfig中来暴露键,以便外界能够使用自定义的键,在每个模式下配置文件中的Key要保持一致,关于Scheme系统默认提供Debug和Release两种模式,也可以自定义其他模式
注意特殊字符(/)可能需要使用\转义,有时候不转义字符串会自动截断的,这里好像不转义也可以
注意:使用#include语法来包含其他配置文件,如#include "Common.xcconfig", 最好是放在文件的最后面,放在文件的开头也可以
注意:Common.xconfig中第一个键的配置必须有 :GCC_PREPROCESSOR_DEFINITIONS = $(inherited),没有Xcode会报错
暴露自定义键时的语法: 宏名='$(key)', 在代码或其他地方使用宏名来引用,'$(key)':通过key来指定每个模式下的对应的自定义键的名字,通常将宏的名字和key的名字保持一致, 注意 等号前后一定不能有空格
特别注意:Common.xconfig中第一个key是GCC_PREPROCESSOR_DEFINITIONS = $(inherited) 后面跟自定义的key,注意在第一个key后面跟上自己定义的key的时候一定不要回车换行,敲一个空格,然后在同一行后面追加就行了,换行会编译错误, 不能换行,不能换行,不能换行!
3、 切换到PROJECT—->info—>Configurations下,分别配置Debug和Release模式下对应的.xcconfig配置文件,当创建了.xcconfig文件后,在每个模式下自动作为一个选项来选择,这样直接选择.xcconfig对应的文件名字即可
配置完成后可以看到在TARGETS(目标)—>Build Settings—-> Preprocessor Macros:在Debug和Release下分别出现了刚才配置的API_URL,如果出现说明配置生效了,如果没有看到试着先编译一下
只要新建.xcconfig并且配置了PROJECT—->info—>Configurations,不用包含Common.xcconfig,在User-Defined就能看到自定义的键,但是这里的键并不能在代码中使用,因为自定义键还没有暴露出来
当在Common.xcconfig中暴露了Debug和Release中自定义的键时此时Preprocessor Macros才能看到自定义的值会出现,此时代码中才能访问自定义的键
4、在代码中使用配置的key
xcconfig的其它作用
xcconfig的功能不止用于项目中环境变量的配置,对于一个App对应于多个Target,而每一个Target对应于不同的参数,此时也可以对每一个Targe配置对应的.xcconfig文件,上面操作是针对于整个项目,还可以具体到项目中的每个Target进行配置
xcconfig还可以配置info.plist中的配置,如Bundle name, Bundle Identifity
xcconfig还可以配置一些Xcode的编译的变量