iOS项目的多环境配置

406 阅读3分钟

iOS项目的多环境配置

1. Xcode 中常见的概念

  1. Project - 所有配置xcconfig, 代码C/C++/OC/Swift, 资源info.plist, Assets等等
  2. Scheme - 旁观者, 控制编译的完成的配置, 可以设置 xcconfig, deploy target, build 附加的监控工具
  3. Target - 真正的打工人, 所有的编译配置build settings, build phase, Build Rules....

2. 历史上最简单的多环境方式 -- 多个Targets

使用多个Targets时, 就是多了一份编译构建的配置, 修改某一个Target的编译配置, 不会影响其他的Target, 例如不同的APP名称, 不同的info.plist

  1. 直接在Targets中 copy一份新的Target copy, 简单来说就是拷贝了一份编译关联的配置.
  2. 此时会自动创建一个新的 xxx-Info.plist, 我们可以在这个新的 target中修改不同的配置, 来满足我们不同环境的需求. 例如修改不同的Bundle Display Name, Product Bundle Identifier
  3. 此时我们发现, 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/ReleaseMacro

如果我们增加一个 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两个构建配置.

此时,在 SchemeBuild Configuration 参数就能配置我们自己的Configuration -- Dev.

我们打开Target -> Build Settings, 然后设置All/Levels 就能看到大量的配置可以分别设置Debug,ReleaseDev的专属配置.

3.1 创建自己的 Configration 对应的 Scheme

手动在New Scheme中创建一个名称为MyApp-Dev, TargetMyAppScheme, 后续所有的配置都基于我们自定义的Scheme进行.

Edit SchemeMyApp-Dev修改Info里面的Build ConfigurationDev

3.2 使用User-Defined Setting创建自己可配参数

  1. 例如创建一个HOST_URL变量, 可以根据Debug/Release/Dev配置不同的参数
  2. Info.plist中增加K-V 参数: HOST_URL: ${HOST_URL}
  3. 在代码中直接读取Info.plist的该变量
  4. 或者在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:

  1. Pods/Target Support Files/Pods-MyApp/Pods-MyApp.debug.xcconfig
  2. Pods/Target Support Files/Pods-MyApp/Pods-MyApp.dev.xcconfig
  3. 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…