iOS新建target,使两个不同项目共用某一模块
一、背景介绍,为什么要新建target?
公司的一个新需求,需要在原有的企业版app基础上,新做一个用户版的app。由于两个app大部分内容很相似,而且有一个共用的业务模块。
大概情况如上,而痛点
如下:
- 虽然大部分内容一开始相同,但后面分歧会越来越大,毕竟是两个app,各有各的业务,所以这大部分相同的代码,将会被
拷贝成两份代码
。 - 共用一个业务模块。在第1个痛点的时候,我们已经把不共用的代码拷贝成两份了,如果共用模块也拷贝两份代码的话,那以后共用模块出现修改的话,就需要在
共用模块的两份代码都修改一遍
,容易出错。 - 共用模块也会出现小部分的两个app
不同的业务处理
。
针对以上三个痛点,新建一个target正好可以解决这几个问题。
二、如何新建target?
新建target有两个方法。
方法一:复制target
在已有的target上,已有target
-->右键
-->Duplicaate
-->Duplicaate Only
。
复制成功后,工程目录下会出现copy-Info.plist文件。
方法二:新建target
通过菜单
-->Editor
-->Add Target
--> Application
--> Singe View Application
--> Product Name
新建成功后,工程目录会出现新target目录,里面会包含以下文件
新出现的文件方法一、二的不同点:
方法一中,新target保留了被拷贝的target全部配置和文件引用,只需稍作修改就能生成一个新的app(比如修改包名、图标和启动图之类的)。
方法二中,新target将不保留被拷贝的target全部配置和文件引用,相当于一个全新的app(Singe View Application)。
三、不同的target作用
每个Target都包含了Copy Bundle Resources
, Compile Sources
, Link Binary With Libraries
、info.plist
等,对不同的app进行管理。
其作用如下:
-
Copy Bundle Resources
是指生成app后里面所包含的资源文件,比如图片。 -
Compile Sources
是指哪些源代码会被该target引用编译。 -
Link Binary With Libraries
是指引用哪些库文件。 -
info.plist
,这个应该都是知道是比较重要的,比如包名、版本号和权限之类的。
四、选择方案
为了解决上面的第1个痛点,我选择方法二来新建target
。因为方法一
会引用原有的大部分源代码,不符合我需要拷贝两份代码的需求。
好了,方案确定了,就准备大干一场了,因为方法二会相对复杂很多,也会报很多的错误,接下来一一解决。
五、开始新建target工作
1、使用方法二新建target
2、新建一个共用模块文件夹
468468465.png3、把需要共用模块的代码(看你的需要),拷贝到CommonModule的finder目录下。
498446486.png4、在工程中目录中,彻底删除原target中共用模块代码。(Move to Trash)
5、再把这些共用模块代码拉到CommonModule工程目录下,Add to选中: 原target+新target
BEE2D83C-4AA6-4EC8-88F6-19B40CFF8855.pngPS:(2、3、4、5概括来说就是:共用模块独立出来,并被新旧两个target所引用)
6、在工程中目录中,彻底删除新target里的所有东西
首先,彻底删除掉这几个文件:
删除的文件 彻底删除如果新target的finder目录下还有一些空文件夹,也全部删除。
7、把原target的finder目录下所有文件,拷贝到新target的finder目录下。
8、把新target的finder目录下所有文件,拉到新target的工程目录下。Add to选中:新target
1449846515616.png9、至此,新建target的前期工作就完成了,剩下的改配置、修复报错和修复引用之类的了。
六、CocoaPods在多target中安装相同pod的优雅解决方案
如果工程中使用了CocoaPods,请参考这篇文章解决。
七、修改新target的配置
1、下图的配置修改我就不详细说了,作为iOS开发者应该都懂。
1351151561.png2、然后就是设置编译宏来区别代码
分别在新旧两个target的Build Settings中搜索Preprocessor Macros然后增加宏(这里用IsUserTarget=1)
468486446136.png然后在代码中验证一下就知道了。
884616846.png八、修复报错
首先,切换target编译一下,看一下报什么错(每个人的报错可以不一样,这里只解决我遇到的)
263161516.png报错1:
The “Swift Language Version” (SWIFT_VERSION) build setting must be set to a supported value for targets which use Swift. This setting can be set in the build settings editor.
解决1:
这里说swift版本的问题,在新target的Build Settings中搜索swift language,把版本改为你所需要的。
1651646416.png报错2:
No known class method for selector 'yy_modelWithJSON:
解决2:
没有方法yy_modelWithJSON。因为YYModel我是加到pch预编译头文件里面去了,所以这个报错就是pch没有正确引用。
在新target的Build Settings中搜索prefix header,然后添加一下路径。
48484156165.png报错3:
NSTimer+Blocks.m:16:12: ARC forbids explicit message send of 'release'
解决3:
NSTimer+Blocks.m这个文件是使用MRC的,所以要改为ARC。
在新target的Build Phases中搜索NSTimer+Blocks,然后改为ARC。
1568161651.png