背景:在一个现有的项目扩展多渠道,考虑到以后的维护,希望能用一套代码,不同的资源文件和配置,实现切换target即可打包不同渠道包。
渠道包的需求:
1,部分业务逻辑不同(代码不同)
2,配置不同(证书,bundleID,等等)
3,部分字符串不同(如推广文本,公司名称等)
4,部分页面UI不同
技术方案分析:
1,条件化编译
2,配置,可以使用一个渠道对应一个target的方式实现。
3,字符串,因为项目要多语言适配,可以尝试使用多个.xcstring文件来实现。
4,目前项目中UI大部分是stroryboard来实现的,少部分由纯代码实现,storyboard可以准备两套UI,通过代码控制跳转哪个,同时根据具体情况,不通target中同一VC的不同交互控件可以锚定代码中同一方法,或锚定不同方法。纯代码UI可以用代码来控制UI及交互。
一,分渠道配置target(解决配置,及宏定义)
Xcode->targets->右键主target->Duplicate,即可复制一份配置,可以将证书,bundleID等改为渠道要求的内容
1,宏定义:
OC的工程,可以很容易使用宏定义来实现代码的选择性编译:
#define target1 0
#define target2 1
#ifdef target1
#define
//渠道1的代码
#else
//渠道2的代码
#endif
swift并没有设计宏定义,但swift条件编译类似宏定义:
需要在xcode新建的target中设置,其中Swift Compiler - Custom Flags 下的配置即可实现条件编译。而Apple Clang - Preprocessing下的配置则是当OC和Swift混编时,OC部分也需要用到这些宏定义时,需要配置的。

2,GroupID,Domains等问题:
当修改其中一个target的时候,部分配置会自动同步到另一个target,比如GroupID,Domians。导致一些配置每次切target还是需要手动修改,详细内容待补充
最新进展,通过复制一份entitlements文件,并为不同的target配置不同的文件,这样在切换target后,可以配置正确的GroupID和Domains。
配置位置:Target-对应target- Build Setting-Signing:CodeSigning Entitlements


二,分渠道适配字符串
1,有了条件编译,代码中字符串即可分渠道来赋值了:
#if CHANNEL1
let cl_APPID = "xxxx"
let cl_needCheck1 = false
let cl_Appname = "appName1"
let cl_Company = "Company1"
let Channel_bundle = "Localizable_1"
#elseif CHANNEL2
let cl_APPID = "xxxx"
let cl_needCheck1 = false
let cl_Appname = "appName2"
let cl_Company = "Company2"
let Channel_bundle = "Localizable_2"
#else
let cl_APPID = "xxxxxx"
let cl_needCheck1 = true
let cl_Appname = "appName3"
let cl_Company = "Company3"
let Channel_bundle = "Localizable_3"
#endif
2,分渠道多语言适配
默认的多语言适配文件为:Localizable.xcstring.可以在项目中添加多个xcstring文件,并设置其Target Membership为不同的target,然后通过代码来实现分渠道多语言适配。
//NSLocalizedString 为多语言适配方法,Channel_bundle为上一步中宏定义来条件编译的字符串,值为每个target对应的xcstring文件名
let yinsixieyiText = NSLocalizedString("隐私协议文本", tableName: Channel_bundle, comment: "")
这样就可以实现分渠道适配不同字符串,以及在代码中增加逻辑来进行功能适配:
label.text = cl_Company
....
func check(){
if cl_needCheck1{
//do something
}
}
三,分渠道使用资源文件
一般工程里面都是会用Assets包来管理图片,颜色等资源文件
我们只需要在文件目录中New File->Asset Catalog新创建一个资源包,并选中,在最右边Target Menbership中选定生效的target,就可以分渠道使用不同资源包了。
