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.xcconfigPods/Target Support Files/Pods-MyApp/Pods-MyApp.dev.xcconfigPods/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…