总结
通过多target编译方案,我们可以很方便的实现多个相似App的开发,以保证我们能够快速地推出多个相似课程的客户端。同时,由于在一个工程中,我们也可以方便地新的代码逻辑在各个课程下是否正常。
该方案可以用来解决“维护大量逻辑相似但是又有细微不同的应用”的需求,希望本文能给业界同行一些帮助。
本文共 3323 字,大约阅读时间需要 11 分钟。
本人今年主要在负责猿题库客户端的开发,本文旨在通过分享猿题库客户端开发过程中的技术细节,达到总结和交流的目的。
这是本技术分享系列文章的第一篇。本文涉及的技术细节是:采用多Target编译方案来实现多个相似App的开发,以保证我们能够快速地推出多个相似课程的客户端。
今年春节后,我们对外发布了应用,接着我们就开始一个个发布猿题库系列课程应用。到现在半年多过去了,我们一共对外发布了8款应用(如下图所示)。
这些课程,随了和其它课程不一样之外,另外7个课程都有着相似,但是又不完全相同的功能和界面。
这些应用的相同点包括:
不同点主要包括:
我们的技术解决方案主要说来分4步:
我们首先做的是抽取子项目,从开始,我们将可以重用的模块一一抽取出来,以submodule的形式组织到项目中。这个抽取过程在开发完猿题库司法考试客户端之后,基本成型了。我们抽取的submodule主要分为4部分:
以上只是粗粒度划分,这些模块化的子项目可能在以后被重用,例如Core Common完全就可以复用在任何其它项目中。
抽取完子项目以后,我们采用多target的方式,将不同课程中的同名资源文件打包进各自的Target中,最后所有课程在一个工程项目中,如下图所示:
先简单介绍一下Xcode中target的概念,苹果在文档中写道:
Targets that define the products to build. A target organizes the files and instructions needed to build a product into a sequence of build actions that can be taken.”
在Xcode的一个项目中,可以允许建立多个编译的target,每个target代表着最终编译出来的一个App文件,在每个target中,可以添加不同的编译源文件和资源文件。最终,通过我们在不同target之间,修改其 Copy Bundle Resources
和 Compile Sources
配置,使课程之间的差异性得到实现。我们具体的配置方案如下:
我们的每个课程的资源文件都具有相同的文件名,例如首页背景都叫 HomeBackgroundBg.png ,由于每个课程背景不一样,所以我们在工程中,每一个课程target下,通过修改Copy Bundle Resources
,使其都配置有不同的(但是同名) HomeBackgroundBg.png 。这样的好处是,在代码逻辑层面,我们可以完全不用处理课程间资源文件的差异性问题。资源文件的差异性都是通过配置文件来保证的。
对于文案一类的差别,我们通过修改Compile Sources
,使不同的课程有着不同的文案定义文件。通过这样,我们使不同课程有了不同的文案。另外包括后台网络接口的差异性问题,统计项的差异性问题,也都是这样处理的。
最后,我们使用Config类来完成交互和页面UI组件差异性问题。拿能力评估报告页面来说,不同的课程的页面都有一些差异。我们在公共层的代码中将这些逻辑全部实现,具体的UI在呈现时,通过读取相关的Config类来决定具体如何展示。这样,我们只需要在第2步提供的各个课程的差异性源文件中,完成Config类的配置即可。
有些时候,我们仅仅需要的是UI界面排列方式不一样,其它交互逻辑完全一样。对于这种需求,我们尝试同一个view对应有多个xib,然后通过上一步的Config类的信息,来加载不同的xib界面。这样所有的差异性都在不同的xib中解决了,对controller层可以完全透明。
下图是我们报告页面的xib界面,分为:高考课程、有目标考试的课程、没有目标考试的课程三种。由于这3个界面的后台逻辑和交互逻辑都一样,我们通过3个xib来实现它们之间差异性的部分。
以下是view加载对应的xib的代码逻辑:
+ (IPadAbilityReportHeaderView *)loadFromNib:(IPadAbilityReportHeaderViewType)type {
NSString *nibFileName;
switch (type) {
case IPadAbilityReportHeaderViewTypeWithQuiz:
nibFileName = @"IPadAbilityReportHeaderViewWithQuiz";
break;
case IPadAbilityReportHeaderViewTypeWithoutQuiz:
nibFileName = @"IPadAbilityReportHeaderViewWithoutQuiz";
break;
case IPadAbilityReportHeaderViewTypeGaokao:
nibFileName = @"IPadAbilityReportHeaderViewInGaokao";
break;
default:
break;
}
NSArray *nibArray = [[NSBundle mainBundle] loadNibNamed:nibFileName owner:nil options:nil];
if (nibArray.count > 0) {
return [nibArray lastObject];
} else {
return nil;
}
}
通过多target编译方案,我们可以很方便的实现多个相似App的开发,以保证我们能够快速地推出多个相似课程的客户端。同时,由于在一个工程中,我们也可以方便地新的代码逻辑在各个课程下是否正常。
该方案可以用来解决“维护大量逻辑相似但是又有细微不同的应用”的需求,希望本文能给业界同行一些帮助。
转载地址:http://budws.baihongyu.com/