咱们在iOS开发中可能会遇到同时开发多个相似项目的状况。这些项目大同小异,有诸多代码能够共用,若是每一个项目都分别开发,这在后期的迭代中会十分繁琐。为了解决这个问题,使用多Target开发是一种比较好的选择,本文就这一技术实现进行简要总结。express
1、理解项目中的Porject与Targetui
使用Xcode来开发项目,其中的Project是一个总体项目至关于一个仓库,包括了全部的代码和资源文件。而Target至关于一个具体的产品,包含了对于代码,资源文件的具体使用规则和配置。一个Project能够包含多个Target,也就是说经过不一样Target咱们能够生成不一样的APP。3d
2、多Target开发项目的实践步骤code
使用多Target来建立项目,就以我当前正在开发的亲戚买房APP为例。需求是这样的:亲戚买房是一个为买房人提供砍价服务的APP,APP的用户须要区分为用户,专家和砍价师三个用户群体。因此这里以Customer,Consul,Bargain三个Target来开发应用blog
以QQMF(亲戚买房)为名建立一个新的工程以下:token
建立三种Target资源
建立新Target的方式有两种:开发
第一种:依次选择File->New->Target,而后选择一个模板(一般是Single View App)来建立。只是这样建立的target带有Appdelegate和main等文件,在这里并不会用到这些文件,因此咱们采用第二种方式建立。get
第二种:产品
在Targets中点击已有的Target,右键选择Duplicate能够复制生成一个copy的新Target,而且在文件目录中生成对应的copy-Info.plist文件。这样生成的target与被拷贝的target类似度很大,减小了过多的修改。一般为了减小后期的修改,咱们也会首先在原有的Target中修改一些配置以后再Duplicate。
执行了Duplicate操做以后的效果以下:
1.修改Targe和plist文件的名称为本身须要的名称
在Target里能够直接修改Target的名称,在文件目录下也能够直接修改plist文件的名称。若是咱们不想文件结构那么乱,也能够像其余文件同样移动plist文件的位置并从新引用到工程中,以下:
特别注意:咱们在移动文件的时候可能须要从新引用文件到工程中,此时add文件的时候必定要注意选择Target,若是是共用文件必定要勾选对应的Target,相似AppDelegate这样文件的操做以下:
2.修改Xcode左上角的Target名称
选中Xcode左上角的建立工程时的Target(QQMF),选择Manage schemes
在以下的schemes中修改Target的名称,这里也能够删除多余的最初的QQMF
特别说明:QQMF是咱们建立工程自带的Target,其实也能够修改它的名字以供自定义使用,而这里咱们是直接删掉了它,这样以后,项目自带的info.plist也是没用的了,也能够删掉。
1.设置Target与plist文件对应
切换到Target目录下,咱们能够在这里删掉用不到的QQMF,选择其中一个Target以后并选择general,而后能够看到每一个Target的右侧都有对应的choose info.plist file选项,点击能够选择与Target对应的plist文件。这也就至关于不一样的Target项目对应了不一样的plist配置。
2.为每一个Target设置Display Name,Bundle Identifier等信息
点击Target->选择General,咱们分别设置不一样项目的名称和BundleID信息,以及证书等
同一份代码区分不一样Target的操做
使用多Target是为了共用一部分代码,可是有些共用的文件在不一样的Target下是有细微不一样的,那么咱们在具体实现的时候就须要做出区分。这里解决的方法是针对不一样的Target定义宏。
首先选择一个Target,如Customer,依次选择Build Settings ->搜索PreprocessorMacros, 在找到PreprocessorMacros以后,咱们分别在Debug和Release中设置TargetType=1以下图进行设置:
其余的Target也是一样的设置方式,只是要区分TargetType的值,分别是2,3(TargetType及其值都是自定义的)。而后就是在代码中的使用以下图,分别选择Xcode左上角不一样的Target运行,查看控制台验证是否成功。
1.解决使用Cocoapods的问题
由于存在多个Target,咱们须要区别的设置不一样target须要的第三方库,以下图。这里可能出现的问题是若是有不少相似AFNetworking这样的被多个Target须要的类库,咱们在删除和增长的时候就会频繁的操做并且会代码冗余。
解决上述问题的比较优雅的作法是以下:
3、遇到的问题
问题:invalid token at start of a preprocessor expression
缘由:这是我在pch文件中判断target类型出现的错误,这句话的大体意思是:在预编译阶段,代码并未运行,没法判断宏定义的值。最后查找到缘由是我在上述步骤设置宏定义的时候,手误设置了TargetType==1,这本是一句须要执行才能获得结果的代码。因此没法在#if的条件编译中经过。
解决:在条件编译中不使用代码运行时才生成的量便可。