缘由
刚进公司,翻看以前的工程项目,项目没有按照一定的组织计划和标准进行构建。并且,直接在项目上进行重构会有很大的阻力和风险。领导层也知道相关问题的存在,如果项目还是以现在的方式继续进行代码堆叠,势必将来会更加难以接手和维护,所以重新进行两个工程项目的重写得到支持。
风险
虽然已经确定对两个项目进行重写,但是业务方面也停下来是挺危险的一件事情,毕竟我们是因为架构的优化而重新写了一遍。我原计划的是,自己先编写基础公共的模块,其他两位开发人员继续业务代码上的开发。等到我这边工作完成的时候,他们可以很快切入进来,并且也不耽误现有的需求计划。不过鉴于领导层的鼎力支持,好吧~项目的优化成为了当前工作的重中之重,然后自己作为实践人,肩上也少不了压力。
思路
因为两个项目只是同一款应用做 iPhone 和 iPad 版的区分,业务大体上相同。所以萌生了制作基础公共库的想法。然后两个版本分别依赖这个基础库,就可以免了相关模块的重复开发和维护。又鉴于该库还依赖于一些三方的支持,所以在此基础上添加了Cocoapods的依赖包管理。当时设计的方案是:framework、 一样作为独立的project添加到 workspace 中去,不过由于多个工程之间的版本管理方案没有达到合理的程度,所以作罢。
合理的版本管理方案:
要求:每个工程之间应该是独立的;
问题:
- 通常我们是在每个工程目录的文件夹下为创建 Git 管理,正常的逻辑是一个workspace包含 framework、iPhone、iPad、cocoapods,然后每个 project 都包含一个git管理,所以我们应不应该为了workspace这个总目录来创建一个新的git仓库?亦或者将workspace这个工作台放在其中的某个project中?
- 如果创建一个版本控制去单独维护 workspace 的话,那么此刻这个git仓库将会包含所有 project 项目上的改动,将会重复。
- 如果只配置一个总git仓库,那么其它 project 不免失去了独立性的意义。
也因为创建不同 project 没能协调好 cocoapods 引入导致的一些问题,所以采取了另外一种方案,那就是创建多个target而不是project,这样保持了一个project意义的完整性。
方法
公司切换到 swift 的开发洪流当中,首先我们新创一个 swift 语言的 project:因为是制作 framework 为目的,所以选择iOS平台下的Cocoa Touch Framework
框架,然后依次填写工程的相关信息,最后生成该project。
创建新的 Target —— iPhone 和 iPad,并为其添加本地创建的依赖库支持;
最后为工程配置cocoapods:终端进入project目录,键入pod init
来生成 podfile 文件,打开 podfile 文件输入自己需要的依赖库,因为标题是OC与Swift 混编,所以也引入两个不同的开发语言,看出现什么意外的效果;
配置好 Cocoapods 之后,我们来为自己创建的 frame 添加相关的代码吧。首先打开工程的 workspace,在 自己创建的 framework 中创建 OC 类,然后编写相应的实例方法,并在工程的头文件中导入需要暴露给其它 targetd的OC头文件(swift文件可以忽略这步),最后对该framework进行编译,在你需要的 target 中导入 framework 即可使用。
很多坑
也许你以为跟着这些步骤就好了,其实还有不少坑。
比如你在 framework 中写OC与swift混编的东西,就得多注意这两者语言的特性了。
- OC 调用 swift 的属性:你得将 swift 中的属性用
@objc
声明为对象,并且赋予 open 权限; - 关于 swift4.0 的 json 转换对象特性: Codable协议,如果你是打算在 OC 中直接使用 swift 的 Json 编解码特性的话,找到了方法一定要告诉我。我查了下关于这部分的内容,OC语言并没有这方面的文档资料,所以它们之间并不互相直接支持,你得编写个 swift 模型的编解码包装,然后暴露给 OC 使用;
- 很多 swift 过于强大的新特性,你不能在 OC 中使用 enum、struct 中的方法、协议,不能使用元组 等等。
初次编写技术文,如果写的不对就是误人子弟了。所以有遇到问题、纠正或建议的希望能和我联系,不胜感激。