iOS之深入解析多环境配置的实现方案
Posted Forever_wj
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS之深入解析多环境配置的实现方案相关的知识,希望对你有一定的参考价值。
一、多 target 形式配置多环境
- 如下所示,选择工程 TARGETS,新创建一个 targets:
- 创建完成后,可要发现产生了一个 plist 文件,这个 plist 就是对应新创建的 target:
- 修改 target 名为 LoginApp-Dev,target 是一个全新生成的,因此需要修改 bundle ID,设置为 com.ydw.LoginApp-Dev,同时它也有一个自己的 plist 配置文件,也就是上面一起生成的,也修改为 LoginApp-Dev-info.plist,如下所示:
- Build Setting 中的 plist 如下:
- 为新的 target 添加新的 AppIcon,如下所示,创建一个 AppIcon:
- 再到 Build Setting 里将 icon 重新设置一下,这样两个 target 就可以展示不同的 icon:
- 编译运行,可以发现两个 target 会生成两个 App:
- 平时如果需要在 dev 和 release 环境下执行不同的代码,一般是需要定义宏来进行区分,而项目默认有个宏 DEBUG,其实是在下面自定义的:
- 可以自定义一个 dev 在 debug 环境下等于 1,在 release 环境下等于 0,如下所示:
- 测试可以发现在 release 和 debug 模式下运行,可以看到打印的结果是不一样的,说明我们定义的宏起作用了。
- 在 Swift 模式下,需要特定的设置方式,可以在 other Flags 里面创建一下变量在 Swift 代码下使用,但是要在定义的变量前面加个 -D:
- 这样,在 Swift 类里面便可以使用:
- 假如项目有多环境,而 debug 和 release 两个环境不足以使用,那只需要在不同的 target 下将宏定义成不同的值,即可更换不同的环境。可以看到这种方法比较繁琐,每个环境都有不同 plist 文件,还需要在每个 target 下进行配置等,配置麻烦。
二、多 scheme 方式配置多环境
① 概念说明
- Project:包含了项目所有的代码,资源文件,所有信息;
- Target:指定代码和资源文件的具体构建方式;
- Scheme:指定 target 的环境配置。
② 添加 Config
- 运用多 target 形式配置多环境,可以看到不同的环境可以在不同 Config 下进行配置,target 下只有 debug 和 release,如果可以需要多种配置,就不必使用多个 target 配置了,我们可以给 Project 添加几个 Config,如下所示:
- 现在添加一个叫 Beta 的 Config:
- 然后到 Edit scheme 里面,可以看到 build Configuration 变成了三种模式:
- 并且 target 下所涉及到的配置地方也都变成三种模式:
③ 添加 scheme
- 利用多 scheme 方式,每次都需要在 Edit scheme 里面修改 scheme 对应的配置环境也显得比较麻烦。不过可以在 manager scheme 里面进行添加 Scheme,这样就能在同一个 target 下,直接切换不同的 scheme 来进行环境的切换:
- 再看一下项目的 scheme,可以发现能直接进行切换:
④ 将不同的 scheme 配置对应的 config
- 为了将不同的 scheme 配置对应的 configuration,可以在 Edit Scheme 里面进行配置,如下所示,将不同的 scheme 配置不同的 configuration 即可:
⑤ 在 user-Defined中 添加需要的变量
- 在 Buidle Settiongs 里面添加一个自定义的 User-Defined:
- 可以看到自定义的 User-Defined 里面也区分了三种 configuration,因此可以在不同配置下定义不同的值,如下所示,配置不同环境的 URL 地址:
⑥ 通过 info.plist 将定义的变量公开出去
- 由于直接通过代码无法获取配置的值,但是可以通过代码获取 plist 文件的设置,因此可以在 plist 里面将配置的变量公开出去,然后在代码中读取 plist 的内容:
- 如下所示,可以发现在不同的配置下读取的值是不同的:
- 运用这种方式,可以通过这种方式让代码在一种环境下运行,在一种环境下不运行,同时也可以在可以配置的地方配置不同环境下的内容。比如“图标配置”如下:
三、运用 config 配置文件配置多环境
① Cocoapods 创建的配置文件
- 使用过 Cocoapods 的都知道,工程中会产生如下的配置文件:
- 进入到 project 的 configuration 也可以看到:
- 这些都是 Cocoapods 创建的,那么手动来创建一个配置文件是否能生效呢?
② 创建 config 配置文件
- 创建 config 配置文件入口如下:
- 创建两个 config 文件,文件名命名需要遵守如下形式:文件名 + 工程名 + 环境名:
③ 将 config 文件配置到对应的 configuration 中
- 将 config 文件配置到对应的环境中:
- 也看到 Target 也可以选择配置文件,因为在 Target 的 BuildSetting 里面也有相应环境的配置,也可以通过 config 文件进行配置。
④ 在 config 文件中定义相应的变量
- 在三个 config 文件中分别创建一个变量 URL_HOST,如下:
- 在 plist 里面将配置文件的变量公开出去:
- 再用代码读取:
NSString *path = [NSBundle.mainBundle pathForResource:@"Info" ofType:@"plist"];
NSDictionary *infoDic = [[NSDictionary alloc] initWithContentsOfFile:path];
NSLog(@"%@",infoDic[@"URL_HOST"]);
- 这样就可以实现,在 Dev、Release、Beta 三种环境下,分别读取对应的 URL_HOST 的值。
- 这样一来,通过 config 配置文件进行配置比 scheme 方便很多,因此可以将多 config 配合多个 scheme 一起使用,这样会更加灵活和简便。并且,配置文件可以配置更多的内容,包括 buildSetting 里面所有涉及到环境的选项,例如 Other Linker Flags,可以在 config 配置上 OTHER_LDFLAGS。
- 编译一下,便可以在 buildsetting 里看到 Other Linker Flags 中:Beta 里面配置上了 framework。
- 其实 OTHER_LDFLAGS 就是配置到链接器里面,本质上 Config 文件是 key-value 形式进行配置的,既然 OTHER_LDFLAGS 可以配置,那 Build Setting 里面所有涉及到环境变量的参数都能配置,还有很多参数都可以配置,具体可以参考:
- 综上,我们可以通过 config 文件对 Build Setting 进行配置,也就是可以将配置从 buildSetting 分离出来,然后通过环境的不同进行配置。
- 如果项目中有多个 config 文件应该怎么处理呢?config 和本身 Build Setting 里面的配置会不会产生冲突呢?在项目中使用 Cocoapods,然后 pod install 时候会发现 Cocoapods 会提示如下警告:
[!] CocoaPods did not set the base configuration of your project because your project already has a custom config set. In order for CocoaPods integration to work at all, please either set the base configurations of the target `LoginApp` to `Target Support Files/Pods-LoginApp/Pods-LoginApp.debug.xcconfig` or include the `Target Support Files/Pods-LoginApp/Pods-LoginApp.debug.xcconfig` in your build configuration (`LoginApp/Config/LoginApp.Dev.xcconfig`).
[!] CocoaPods did not set the base configuration of your project because your project already has a custom config set. In order for CocoaPods integration to work at all, please either set the base configurations of the target `LoginApp` to `Target Support Files/Pods-LoginApp/Pods-LoginApp.beta.xcconfig` or include the `Target Support Files/Pods-LoginApp/Pods-LoginApp.beta.xcconfig` in your build configuration (`LoginApp/Config/LoginApp.Beta.xcconfig`).
[!] CocoaPods did not set the base configuration of your project because your project already has a custom config set. In order for CocoaPods integration to work at all, please either set the base configurations of the target `LoginApp` to `Target Support Files/Pods-LoginApp/Pods-LoginApp.release.xcconfig` or include the `Target Support Files/Pods-LoginApp/Pods-LoginApp.release.xcconfig` in your build configuration (`LoginApp/Config/LoginApp.Release.xcconfig`).
- 这个警告就是 Cocoapods 检测到了工程手动配置了 config 文件,但是它没有自动兼容配置,需要我们将 Cocoapods 生成的 config 文件导入到自定义的 config 文件里。例如,在 beta 配置文件中,通过 include + 文件路径导入,导入 pod 的配置文件之后在进行 pod install,可以发现警告消除了,如下:
#include "Pods/Target Support Files/Pods-LoginApp/Pods-LoginApp.beta.xcconfig"
- 这样一来,Cocoapods 对应的配置文件便可以引入成功,但是如果手动的配置文件和 Cocoapods 的配置文件里都有相同的配置内容,那么哪个会生效呢?如下,Cocoapods 的配置文件和手动配置文件都有 AFNetworking 三方库的配置:
- 可以看到,在 Cocoapods 配置文件中有一个关键字: $(inherited) 可以理解为“继承”的意思,它会将导入的 Config 文件里相同变量的值拼接起来,但是在 Build Setting 里面只会显示 inherited 里面本身所配置的,还有配置的 Config 文件里面的信息,但是实际上所有的信息都是导入的。因此在对应的 Config-LoginApp.Beta.xcconfig 文件中,修改如下:
OTHER_LDFLAGS = $(inherited) -framework "AFNetworking"
- 然后在 Build Setting 便可以看到配置成功,工程中便可以正常使用这个三方库了。如下所示:
- 参考示例:iOS之深入解析多环境配置的实现方案。
以上是关于iOS之深入解析多环境配置的实现方案的主要内容,如果未能解决你的问题,请参考以下文章