在开发工作中,我们经常性的会随着开发环境的变化而使用不同的配置,我们现在是有开发、测试、发布三个环境,每个环境都有自己的接口访问地址,以及一些第三方SDK的Key配置,这些东西有点经验的都会集中到一个头文件或者pch文件中定义成不同的宏块,这样每次改变环境只要去这个文件修改就可以。
//开发
#define BaseURL @"192.168.102.111:8080/appname/api"
#define PublicKEY @"3TTY59QWE3RWR00WRET3C23WURI22R2X"
//生产
//#define BaseURL @"http://api.appname.com"
//#define PublicKEY @"5FH53UB5M932R7O7M2XQWTDG42G75343"
但是这样也不是没有问题 如果哪次上线忘了修改,后果就非常严重了,毕竟手动操作,无法控制其保险成都。
为了解决手动修改的问题 我们可以通过Debug模式来定义,这样APP发布的时候就不用手动修改 会动态匹配。
#ifdef DEBUG
#define BaseURL @"192.168.102.111:8080/appname/api"
#define PublicKEY @"3TTY59QWE3RWR00WRET3C23WURI22R2X"
#else
#define BaseURL @"http://api.appname.com"
#define PublicKEY @"5FH53UB5M932R7O7M2XQWTDG42G75343"
#endif
但这也似乎并非最好的选择,下面我们介绍通过.xcconfig配置文本进行配置切换,该配置文件Xcode会根据当前模式是Debug模式还是Release模式自动选择对应的配置文件去加载。
具体的实行步骤如下:
1.创建三个Configuration Settings File文件,该文件的后缀为.xcconfig, 三个文件的命名分别命名为Common.xcconfig, Debug.xcconfig, Release.xcconfig, Debug.xcconfig和Release.xcconfig可以使用#include来包含Common.xcconfig配置文件, 注意在创建.xcconfig的时候Xcode默认是不会选中Targets的,注意要选中!(如果出来开发和发布还有其它环境也可以再建其它文件,我们项目中现在还有Dev.xcconfig用于测试)
NewFile...->Other->Configuration Settings File->Next->Save As:写入你想叫的名字->Create File
默认targets是不选中的 一定要手动选中!
此时工程中出现Debug.xcconfig文件,依次建立 Release.xcconfig和Common.xcconfig文件
2.分别在Debug.xcconfig、Release.xcconfig中定义键值对,在Common.xcconfig中来暴露键,以便外界能够使用自定义的键,在每个模式下配置文件中的Key要保持一致,关于Scheme系统默认提供Debug和Release两种模式,也可以自定义其他模式。
注意特殊字符(/)可能需要使用\转义,有时候不转义字符串会自动截断的!
Debug.xcconfig
// APP 请求地址
BasicURL = @"http:\/\/test2api.xiaowei.com/rq"
// SDK Key
MOJIE_KEY = @"97XXXXXXXXXXXXXXXXXXXXX1c49"
IS_PRODUCATION = NO //是否是生产环境
#include "Common.xcconfig"
Release.xcconfig
// APP 请求地址
BasicURL = @"http:\/\/api.xiaowei.com/rq"
// SDK Key
MOJIE_KEY = @"f5XXXXXXXXXXXXXXXXXXXXX1c43"
IS_PRODUCATION = NO //是否试生产环境
#include "Common.xcconfig"
Common.xcconfig
GCC_PREPROCESSOR_DEFINITIONS = $(inherited) BasicURL='$(BasicURL)' IS_PRODUCTION='$(IS_PRODUCTION)' MOJIE_KEY='$(MOJIE_KEY)'
A.使用#include语法来包含其他配置文件,如#include "Common.xcconfig", 最好是放在文件的最后面,放在文件的开头也可以
B.Common.xconfig中第一个键的配置必须有: GCC_PREPROCESSOR_DEFINITIONS = $(inherited),没有Xcode会报错
C.暴露自定义键时的语法: 宏名='$(key)',在代码或其他地方使用宏名来引用,'$(key)':通过key来指定每个模式下的对应的自定义键的名字,通常将宏的名字和key的名字保持一致,注意 等号前后一定不能有空格
D.特别注意:Common.xconfig中第一个key是GCC_PREPROCESSOR_DEFINITIONS = $(inherited) 后面跟自定义的key,注意在第一个key后面跟上自己定义的key的时候一定不要回车换行,敲一个空格,然后在同一行后面追加就行了,换行会编译错误
3.切换到PROJECT—->info—>Configurations下,分别配置Debug和Release模式下对应的.xcconfig配置文件,当创建了.xcconfig文件后,在每个模式下自动作为一个选项来选择,这样直接选择.xcconfig对应的文件名字即可。
4.配置完成后可以看到在TARGETS(目标)—>Build Settings—-> Preprocessor Macros:在Debug和Release下分别出现了刚才配置的API_URL,如果出现说明配置生效了,如果没有看到试着先编译一下。
5.只要新建.xcconfig并且配置了PROJECT—->info—>Configurations,不用包含Common.xcconfig,在User-Defined就能看到自定义的键,但是这里的键并不能在代码中使用,因为自定义键还没有暴露出来。
当在Common.xcconfig中暴露了Debug和Release中自定义的键时此时Preprocessor Macros才能看到自定义的值会出现,此时代码中才能访问自定义的键 。
6.在代码中使用键的方法:
NSString *urlStr = [NSString stringWithFormat:@"%@%@",BasicURL,@"question"];
7.之后切换环境只需要product->scheme->edit scheme->Build Configuration 选取响应环境下的配置文件即可。
xcconfig的其它作用
xcconfig的功能不止用于项目中环境变量的配置,对于一个App对应于多个Target,而每一个Target对应于不同的参数,此时也可以对每一个Targe配置对应的.xcconfig文件,上面操作是针对于整个项目,还可以具体到项目中的每个Target进行配置。
xcconfig还可以配置info.plist中的配置,如Bundle name, Bundle Identifity。
xcconfig还可以配置一些Xcode的编译的变量。