iOS多Target开发相似App

2018-04-24 14:49:21 浏览数 (1)

我们在iOS开发中可能会遇到同时开发多个类似项目的情况。这些项目大同小异,有诸多代码可以共用,如果每个项目都分别开发,这在后期的迭代中会十分繁琐。为了解决这个问题,使用多Target开发是一种比较好的选择,本文就这一技术实现进行简要总结。

一、理解项目中的Porject与Target

使用Xcode来开发项目,其中的Project是一个整体项目相当于一个仓库,包括了所有的代码和资源文件。而Target相当于一个具体的产品,包含了对于代码,资源文件的具体使用规则和配置。一个Project可以包含多个Target,也就是说通过不同Target我们可以生成不同的APP。

二、多Target开发项目的实践步骤

使用多Target来创建项目,就以我当前正在开发的亲戚买房APP为例。需求是这样的:亲戚买房是一个为买房人提供砍价服务的APP,APP的用户需要区分为用户,专家和砍价师三个用户群体。所以这里以Customer,Consul,Bargain三个Target来开发应用

  1. 以QQMF(亲戚买房)为名创建一个新的工程如下:
屏幕快照 2017-11-20 上午11.25.03.png屏幕快照 2017-11-20 上午11.25.03.png
  1. 创建三种Target 创建新Target的方式有两种: 第一种:依次选择File->New->Target,然后选择一个模板(通常是Single View App)来创建。只是这样创建的target带有Appdelegate和main等文件,在这里并不会用到这些文件,所以我们采用第二种方式创建。 第二种: 在Targets中点击已有的Target,右键选择Duplicate可以复制生成一个copy的新Target,并且在文件目录中生成对应的copy-Info.plist文件。这样生成的target与被拷贝的target相似度很大,减少了过多的修改。通常为了减少后期的修改,我们也会首先在原有的Target中修改一些配置之后再Duplicate。
 屏幕快照 2017-11-20 上午11.27.06.png 屏幕快照 2017-11-20 上午11.27.06.png

执行了Duplicate操作之后的效果如下:

屏幕快照 2017-11-20 上午11.29.38.png屏幕快照 2017-11-20 上午11.29.38.png
  1. 修改Targe和plist文件的名称为自己需要的名称 在Target里可以直接修改Target的名称,在文件目录下也可以直接修改plist文件的名称。如果我们不想文件结构那么乱,也可以像其他文件一样移动plist文件的位置并重新引用到工程中,如下:
 屏幕快照 2017-11-20 下午6.35.12.png 屏幕快照 2017-11-20 下午6.35.12.png

特别注意:我们在移动文件的时候可能需要重新引用文件到工程中,此时add文件的时候一定要注意选择Target,如果是共用文件一定要勾选对应的Target,类似AppDelegate这样文件的操作如下:

 屏幕快照 2017-11-20 下午6.29.01.png 屏幕快照 2017-11-20 下午6.29.01.png

修改Xcode左上角的Target名称 选中Xcode左上角的创建工程时的Target(QQMF),选择Manage schemes

屏幕快照 2017-11-20 下午6.38.06.png屏幕快照 2017-11-20 下午6.38.06.png

在如下的schemes中修改Target的名称,这里也可以删除多余的最初的QQMF

 屏幕快照 2017-11-20 上午11.47.18.png 屏幕快照 2017-11-20 上午11.47.18.png

特别说明:QQMF是我们创建工程自带的Target,其实也可以修改它的名字以供自定义使用,而这里我们是直接删掉了它,这样之后,项目自带的info.plist也是没用的了,也可以删掉。

  1. 设置Target与plist文件对应 切换到Target目录下,我们可以在这里删掉用不到的QQMF,选择其中一个Target之后并选择general,然后可以看到每个Target的右侧都有对应的choose info.plist file选项,点击可以选择与Target对应的plist文件。这也就相当于不同的Target项目对应了不同的plist配置。
 屏幕快照 2017-11-20 下午2.01.27.png 屏幕快照 2017-11-20 下午2.01.27.png
  1. 为每个Target设置Display Name,Bundle Identifier等信息 点击Target->选择General,我们分别设置不同项目的名称和BundleID信息,以及证书等
 屏幕快照 2017-11-20 下午2.28.17.png 屏幕快照 2017-11-20 下午2.28.17.png
  1. 同一份代码区分不同Target的操作 使用多Target是为了共用一部分代码,但是有些共用的文件在不同的Target下是有细微不同的,那么我们在具体实现的时候就需要作出区分。这里解决的方法是针对不同的Target定义宏。 首先选择一个Target,如Customer,依次选择Build Settings ->搜索PreprocessorMacros, 在找到PreprocessorMacros之后,我们分别在Debug和Release中设置TargetType=1如下图进行设置:
 屏幕快照 2017-11-20 下午6.45.35.png 屏幕快照 2017-11-20 下午6.45.35.png

其他的Target也是同样的设置方式,只是要区分TargetType的值,分别是2,3(TargetType及其值都是自定义的)。然后就是在代码中的使用如下图,分别选择Xcode左上角不同的Target运行,查看控制台验证是否成功。

屏幕快照 2017-11-20 下午6.55.02.png屏幕快照 2017-11-20 下午6.55.02.png
  1. 解决使用Cocoapods的问题 因为存在多个Target,我们需要区别的设置不同target需要的第三方库,如下图。这里可能出现的问题是如果有很多类似AFNetworking这样的被多个Target需要的类库,我们在删除和增加的时候就会频繁的操作而且会代码冗余。
 屏幕快照 2017-11-20 下午7.22.34.png 屏幕快照 2017-11-20 下午7.22.34.png

解决上述问题的比较优雅的做法是如下:

 屏幕快照 2017-11-20 下午7.39.25.png 屏幕快照 2017-11-20 下午7.39.25.png

三、遇到的问题

1.问题:invalid token at start of a preprocessor expression 原因:这是我在pch文件中判断target类型出现的错误,这句话的大致意思是:在预编译阶段,代码并未运行,无法判断宏定义的值。最后查找到原因是我在上述步骤设置宏定义的时候,手误设置了TargetType==1,这本是一句需要执行才能得到结果的代码。所以无法在#if的条件编译中通过。 解决:在条件编译中不使用代码运行时才生成的量即可。

0 人点赞