iOS项目的多环境配置
1. Xcode 中常见的概念
- Project - 所有配置
xcconfig
, 代码C/C++/OC/Swift
, 资源info.plist, Assets
等等 - Scheme - 旁观者, 控制编译的完成的配置, 可以设置
xcconfig
,deploy target
,build 附加的监控工具
- Target - 真正的打工人, 所有的
编译配置build settings
,build phase
,Build Rules
....
2. 历史上最简单的多环境方式 -- 多个Targets
使用多个Targets
时, 就是多了一份编译构建
的配置, 修改某一个Target的编译配置, 不会影响其他的Target, 例如不同的APP名称, 不同的info.plist
- 直接在Targets中 copy一份新的
Target copy
, 简单来说就是拷贝了一份编译关联的配置. - 此时会自动创建一个新的
xxx-Info.plist
, 我们可以在这个新的 target中修改不同的配置, 来满足我们不同环境的需求. 例如修改不同的Bundle Display Name
,Product Bundle Identifier
- 此时我们发现,
Scheme
中也拥有了一个新的 Scheme 配置, 和我们的Target
同名!!!
ps: Bundle Display Name
如果没有配置, 默认会使用 Targe
名称
如果多个Target
, 使用不同的Info.plist
作为参数配置表
前面, 我们在复制Target
时, 系统会帮助我们创建一个新的MyApp_DEV-Info.plist
, 并且在Build Setting -> Packaging -> info.plist File
中配置.
请注意,
Build Settings
大部分配置的路径是以*.xcodeproj
为相对目录的.
2.1 用宏Macro
做条件编译
OC中使用宏
, 宏配置的路径:
Targets
-> Build Settings
-> Apple Clang - Preprocessing
-> Preprocessor Macros
配置自己的 Debug/Release
的Macro
如果我们增加一个 DEVELOPMENT=1
或者 DEVELOPMENT=0
:
- (void)viewDidLoad {
[super viewDidLoad];
#if DEVELOPMENT
self.view.backgroundColor = [UIColor redColor];
#else
self.view.backgroundColor = [UIColor blueColor];
#endif
}
如果是Swift
中也需要使用宏
, 它的配置, 与OC有所不同, 宏配置的路径:
选中 target
-> Build Settings
-> 搜索 Swift Compiler - Custom Flags
-> Other Swift Flags
, 然后设置-D DEV
!!!
如果是 OC 和 Swift 混编的项目,OC也需要用到,则还是在 Preprocessor Macros
里添加一遍.
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let vc = UIViewController()
#if DEV
vc.view.backgroundColor = .yellow
#else
vc.view.backgroundColor = .systemPink
#endif
self.present(vc, animated: true, completion: nil)
}
2.2 OC/Swift混编中, OC引用Swift代码引入头文件的问题
OC/Swift
混编项目中, OC使用Swift代码时, 需要 #import <$(SWIFT_MODULE_NAME)-Swift.h>
, 其中SWIFT_MODULE_NAME
是和Target
名称一致, 并且无法修改.
配置路径参考:
Targets
->Build Settings
->Swift Compiler - General
->Objective-C Generated Interface Header Name
需要配置一个$(SWIFT_MODULE_NAME)-Swift.h
的文件!!!
而我们目前有多个Target
, 并且使用同一份代码, 因此可以使用上面提到的OC Macro
问题解决:
#if DEVELOPMENT
#import <MyApp_Dev-Swift.h>
#else
#import <MyApp-Swift.h>
#endif
...
3. 创建自己的Configuration, 多个Scheme
做选择
在PROJECT -> Info
中选择Configuration
, 创建一个自己的Configuration
, 命名为 Dev
默认情况下,
Configuration
拥有Debug/Release
两个构建配置.
此时,在 Scheme
中Build Configuration
参数就能配置我们自己的Configuration
-- Dev
.
我们打开Target -> Build Settings
, 然后设置All/Levels
就能看到大量的配置可以分别设置Debug
,Release
和Dev
的专属配置.
3.1 创建自己的 Configration 对应的 Scheme
手动在New Scheme
中创建一个名称为MyApp-Dev
, Target
为MyApp
的Scheme
, 后续所有的配置都基于我们自定义的Scheme
进行.
Edit Scheme
将MyApp-Dev
修改Info
里面的Build Configuration
为Dev
3.2 使用User-Defined Setting
创建自己可配参数
- 例如创建一个
HOST_URL
变量, 可以根据Debug/Release/Dev
配置不同的参数 - 在
Info.plist
中增加K-V 参数
:HOST_URL: ${HOST_URL}
- 在代码中直接读取
Info.plist
的该变量 - 或者在
Preprocessor Macro
中, 直接使用LANGCODE="$(HOST_URL)"
定义一个代码中使用的宏
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSDictionary *infoDict = [NSBundle mainBundle].infoDictionary;
NSString *host = infoDict[@"HOST_URL"];
NSLog(@"host: %@", host);
return YES;
}
4. XCConfig 统一管理 Build Setting
类似Cocoapod
, 在项目中创建XCConfig
, 并增加下面的代码, 在其中可以配置各种常见配置, 能在User-Defined Setting
, 中能看到HOST_URL
的参数:
HOST_URL=127.0.0.1
在Info.plist
中增加K-V 参数
: HOST_URL: ${HOST_URL}
, 并且在代码中能直接读取Info.plist
的该变量.
4.1 自定义XCConfig依赖Cocoapods生成的XCConfig
由于很多项目会使用Cocoapod帮助管理依赖, 并且它也会生成以下XCConfig
:
Pods/Target Support Files/Pods-MyApp/Pods-MyApp.debug.xcconfig
Pods/Target Support Files/Pods-MyApp/Pods-MyApp.dev.xcconfig
Pods/Target Support Files/Pods-MyApp/Pods-MyApp.release.xcconfig
如果我们需要使用自定义的XCConfig, 一半来说需要在配置中引入他们:
// 这里是我们自定义的 xcconfig, 先引入cocoapod 的配置
// 引入 Cocoapod 的基础 config
#include "Pods/Target Support Files/Pods-LoginApp/Pods-LoginApp.dev.xcconfig"
// 自定义一些参数, 请注意 $(inherited) 会使用 cocoapods 中本参数的配置.
OTHER_LDFLAGS = $(inherited) -framework "AFNetworking"
// 增加 User-Defined Setting
HOST_URL = 127.0.0.2
参考
xcodebuildsettings.com/ stackoverflow.com/questions/3… www.jianshu.com/p/6d8837a8b… www.jianshu.com/p/39fecc5f7…