iOS高级强化--001:多环境配置

Xcode中的常见名词:

  • Project:包含了项目所有的代码,资源文件,所有信息。
  • Target:对指定代码和资源文件的具体构建方式。
  • Scheme:对指定Target的环境配置。

日常开发中,对于不同环境,例如DebugRelease,项目中的环境变量可能存在差异,此时如何高效的进行多环境配置呢?

方式一:

通过Target进行多环境配置

找到TARGETS,复制一个新的Target

项目中对于新Target,对应生成一个新的info.plist

对新Targetinfo.plist重命名

info.plist改名后,还需要在LoginApp-DevBuild Settings里,找到PackagingInfo.plist File配置项,同步修改info.plist的命名

此时我们可以对两个Target进行不同的配置,例如在LoginApp-DevBuild Settings里,设置宏DEV=1

LoginAppBuild Settings里,设置宏DEV=0

代码中使用#if DEV条件限制,执行不同Target会触发不同的代码分支

运行项目时,可以选择不同Target下的Schemes

不同Target下的Schemes运行后,设备上会产生多个App

使用多Target的缺陷:

  • 生成多个info.plist
  • Build Settings手动配置过于繁琐
方式二:

通过Scheme进行多环境配置

找到PROJECT,添加一个新的Configurations

将新创建的Configuration命名为Beta

此时在LoginAppBuild Settings里,很多配置项都多了Beta的独立设置

选择Edit Scheme...

Bulid Configuration里,也增加了Beta模式的选项。在这里切换不同的Bulid Configuration运行,可以让各自环境的配置生效

当然这样的操作过于繁琐,我们可以针对不同环境,添加各自的Scheme

选择Target,指定Name

这里新建两个Scheme,分别命名为BetaDebug

选择Edit Scheme...,此时右上角的Scheme可以切换,将各自的Scheme选择对应的Bulid Configuration

例如:BetaBulid Configuration选择为Beta

DebugBulid Configuration选择为Debug

LoginAppBulid Configuration选择为Release

运行项目时,可以直接切换Schemes,比之前方便了很多

案例:

日常开发中,例如请求服务端接口,在不同环境下域名可能是不一样的,我们可以针对不同Schemes进行不同域名的配置

来到Bulid Settings,点击+,选择Add User-Defined Setting

添加Host_Url,对应不同Schemes配置不同的域名

Info.plist里,暴露Host_Url供项目使用

代码中,添加读取Info.plist的相关代码

选择Beta运行项目,此时打印Host_Urlhttp//:127.0.0.1

不同编译环境的Schemes运行后,设备上会产生多个App

xconfig文件

使用多Scheme方式可以解决多个info.plist的问题,但是在Bulid Settings中的手动配置并没有改善。这里推荐使用xconfig文件,它可以针对Bulid Settings中的配置项进行统一管理。

xconfig文件并不是Shell脚本,它类似配置文件,Xcode会以KeyValue的方式进行读取。

宏定义

项目内创建Config目录

Config目录下创建xconfig文件

分别创建DebugRelease环境下的xconfig,命名方式建议项目名.环境.xcconfig

打开LoginApp.Debug.xcconfig,写入APP_CONFIG=Debug

打开LoginApp.Release.xcconfig,写入APP_CONFIG=Release

选择PROJECT,针对不同环境配置对应的xcconfig。可以针对Project,也可以针对Target

这里我们针对Target进行配置

Info.plist里,暴露APP_CONFIG供项目使用

代码中,添加读取Info.plist的相关代码

当前项目以Debug模式运行,此时打印APP_CONFIGDebug

打开Bulid Settings找到User-Defined配置项,可以看到它自动加上了APP_CONFIG节点

管理Bulid Settings配置项

日常开发中,当我们要链接静态库或动态库时,需要对Bulid SettingsOther Linker Flags进行配置,这时可以使用xcconfig统一管理

打开LoginApp.Debug.xcconfig,写入OTHER_LDFLAGS = -framework "AFNetworking",其中OTHER_LDFLAGS代表的就是Other Linker Flags配置项

项目以Debug模式编译后,打开Bulid Settings找到Other Linker Flags,在xconfig文件内的配置已经生效

如何找到Bulid Settings配置项在xcconfig中的命名?

Bulid Settings中存在众多配置项,它们在xcconfig中的命名应该是什么?可以通过 xcodebuildsettings 网站进行查看

例如:对Bulid Settings中的Header Search Paths进行配置

打开网站,搜索header search paths

在搜索结果中,可以找到Header Search Paths配置项在xcconfig中的命名

打开LoginApp.Debug.xcconfig,写入HEADER_SEARCH_PATHS = /use/info/inclue(路径随意写的)

项目以Debug模式编译后,打开Bulid Settings找到Header Search Paths,在xconfig文件内的配置已经生效

xcconfig文件的冲突

项目中使用CocoaPods导入第三方类库,这里导入AFNetworkingSDWebImage两个类库


此时Pods也会自动生成xcconfig文件

Pods生成的xcconfig文件内容

自定义xcconfig文件内容

此时问题来了,每种Configuration指定的xcconfig文件只能有一个

如果使用Pods生成的xcconfig文件,自定义的配置项无法生效。而使用自定义xcconfig文件,编译又报错

这种场景使用include关键字,将Pods生成的xcconfig文件导入到自定义xcconfig文件内。此时指定自定义xcconfig文件,可以正常编译使用

另一个问题,当多个xcconfig文件存在相同配置项,例如HEADER_SEARCH_PATHS,此时只有后面的配置项可以生效。打开Bulid SettingsHeader Search Paths配置项,里只有自定义xcconfig文件内的/use/info/inclue

解决方式:使用$(inherited)关键字,继承相同配置项

打开Bulid Settings,此时Header Search Paths配置项,合并了Pods和自定义的xcconfig内容

使用xcconfig文件,同时也可以在Bulid Settings手动配置,配置项之间可以并存

Bulid Settings手动配置,并不会影响到xcconfig文件的内容

对于Bulid Settings配置项的优先级

  • 手动配置Target Build Settings
  • Target中配置的xcconfig文件
  • 手动配置Project Build Settings
  • Project中配置的xcconfig文件
注释

xcconfig文件只有一种注释方式//

引入文件

在创建xcconfig文件的时候,可以根据需求,创建多个。也就意味着,可以通过include关键字导入其他的xcconfig内的配置

#include "Debug.xcconfig"

include引入文件时,如果是以/开头,代表绝对路径

#include "/Users/zang/Zang/Spark/LoginApp/Pods/Target Support Files/Pods-LoginApp/Pods-LoginApp.debug.xcconfig"

include引入文件时,也可以使用相对路径

#include "Pods/Target Support Files/Pods-LoginApp/Pods-LoginApp.debug.xcconfig"
变量定义

按照OC命名规则,仅由大写字母,数字和下划线组成。原则上大写,也可以自由发挥。字符串可以是",也可以是'

相同配置项,使用$(inherited)关键字继承

OTHER_LDFLAGS = -framework SDWebImage
OTHER_LDFLAGS = $(inherited) -framework AFNetworking

等同于将两行配置项的值连起来写

OTHER_LDFLAGS = -framework SDWebImage -framework AFNetworking

引用变量,使用$()${}两种写法都可以

VALUE=Cat
TEACHER=$(VALUE)-${VALUE}

URL变量中存在//

SLASH =/
HOST_URL = http:${SLASH}/192.168.1.100
  • /定义为SLASH变量
  • HOST_URL中使用${SLASH},避免直接使用//变为注释
条件变量

根据configsdkarch对设置进行条件化

OTHER_LDFLAGS[config=Debug][sdk=iphonesimulator*[arch=x86_64]= $(inherited) -framework "Cat"
  • 指定configDebug
  • 指定sdk是模拟器,还有iphoneos*macosx*
  • 指定arch生效架构为x86_64

Xcode 11.4及以后版本,可以使用default,来指定变量为空时的默认值

$(BUILD_SETTING_NAME:default=value)
通过多Target进行代码管理

Target可以对参与编译的代码文件和资源文件进行各自管理, 并且多Target之间不会相互干扰

选择一个Target,选择Build Phases

Compile Sources中,可以对参与编译的代码文件进行添加或删除操作

Copy Bundele Resources中,同样可以对资源文件进行添加或删除操作

Swift宏定义

Build Settings里,设置Other Swift Flags配置项

  • OC的差异是,需要在自定义宏前面增加-D参数

打开终端,使用swiftc --help | grep -- "-D"命令,查看-D参数

  • -D:添加自定义标记设置为true
总结:
  • Target可以控制需要编译的文件
  • Scheme提供了多套环境变量
  • 使用xconfig文件可以更好的管理Bulid Settings配置项

你可能感兴趣的:(iOS高级强化--001:多环境配置)