iOS应用模块化的思考及落地方案(二)模块化自动构建工具的使用

1.0 iOS模块化中的问题

前文已经介绍了模块化的流程及一些常见的问题,咱们在这里再次总结一下。git

在工做中,当咱们开始一个新项目的时候,最早考虑的就是模块化工做。github

模块化工做的想法是很美好的,但是执行过程当中会遇到不少的问题,而这些问题可能会让咱们在工做中举步维艰。shell

  1. 工具使用问题。iOS的模块化通常会使用cocoapods工具,这个工具很强大,内容也很丰富,咱们想要完成模块化工做,须要创建私有库,编写podspec文件,处理资源,编写Podfile文件,创建本地依赖等等。让团队成员每一个人都精通这个工具是没必要要的。所以常常会在使用工具中遇到不易解决的问题,从而浪费大量的时间。swift

  2. xcode设置问题。xcode设置项多如牛毛,不少内容看起来并不直观,须要咱们去查阅官方文档来解决。并且这些设置数量多,使用的频率又少,因此不免会出现这样的状况:每一个人都遇到的问题,而后各自去花时间解决,而后过段时间遇到相同的问题经常就忘记了,还要花时间去查阅解决,形成资源的重复浪费。xcode

  3. 模块间依赖的问题,当你依赖的也是私有库的其余模块(下文中称为自有模块)时,开发中可能要同时修改多个模块,这样就会出如今多个工程中切换的问题。bash

  4. 规范问题,每一个人创建模块的方式可能都不一样,包括工程结构,工程设置等等。这样一来,不一样的模块可能差别特别大,当跨模块开发或者代码交接的时候,可能就会出现难以解决的问题。服务器

  5. 设置的变动修改都是手动修改,有时候不免会由于疏忽,而致使难以发现的错误,当须要处理的模块和依赖较多时,发生错误的几率也会增长。app

2.0 编写自动化工具

为了解决这些问题,让团队可以将精力所有集中到业务开发中,特使用bash shell开发一个构建工具,用于自动化处理模块化的过程当中遇到的设置及工具使用问题。模块化

工具的地址以下:github.com/hardman/AWM…工具

使用这个自动化工具你将会得到以下能力:

  1. 一条命令便可建立模块工程,建立.podspec及Podfile文件,自动安装依赖,工程默认使用静态库,支持Swift和OC
  2. 一条命令便可拉取以前开发的模块,而且安装好全部依赖
  3. 一条命令便可自动打tag,自动更新.podspec文件,将工程推送到pod服务器
  4. 自有模块的列表,将会保存在单独git库中,便于有依赖模块时,可动态加载
  5. 自有模块的依赖都经过.podspec文件使用local path的方式安装,这样当被依赖的模块也须要修改时,不须要打开多个工程

所以,使用这个自动化工具,你不须要了解cocoapods工具,也不须要处理任何工程和工具设置,能够将注意力都集中到业务开发中。

【注】工具使用静态库做为模块的输出文件。

3.0 工具的使用

3.1 基本使用步骤

  1. 将工程clone到本地目录
  2. 打开tools/config修改配置文件
    • modulelistgitaddress.txt:新建一个git库,并将地址保存在这个文件中,地址最好是以git@开头。这个git库用于保存全部自有模块名称及地址。
    • podspecsaddr.txt:再新建一个git库,将地址保存在这个文件中,地址最好是git@开头。这个git库就是你的私有库地址。
    • podspecsname.txt:为你的git库取一个名字,保存在这个文件中
    • 上述3个文件都只有一行
    • dependencypodrepos.txt:这个文件保存你的app依赖的其余pod repos,通常状况下保持默认便可,支持多行,每行保存一个地址
    • 因为这些配置几乎不会修改,考虑将这些文件提交到你本身的git库中
  3. 执行 ./create.sh -n=[模块名] -b=[bundle id] -t=[s|f|r] 便可建立工程
    • 脚本执行过程当中会要求输入一些工程基本信息及所依赖的模块,请认真输入,不要遗漏
    • 建立的工程会自动打开,而且能够直接执行
    • 建立好的模块文件在:工程根目录/modules
    • 例:./create.sh -n=HelloWorld -b=com.helloworld -t=s
  4. 模块开发完毕,须要将代码提交到develop分支,而后执行./push.sh [模块名] [tag]
    • 执行push.sh时,模块必须在develop分支上
    • 执行成功后,你的模块就已经提交成功,能够经过Podfile文件引用了
    • 例:./push.sh HelloWorld 0.0.1
  5. 使用 ./pull.sh [模块名] 便可下载其余未同步到本地的自有模块
    • 执行成功后,会自动下载全部依赖的模块,并经过local path添加到模块依赖中
    • 例:./pull.sh HelloWorld

3.2 如何提高模块所依赖其余模块的版本号

有的时候,当前模块所依赖的模块版本升级了,须要修改当前模块的依赖文件。 有2种方法:

  1. 直接修改文件
    • 须要修改的文件有2个,一个是文件根目录的dependency.txt文件,文件内记录了当前模块依赖的自有模块
    • dependency.txt文件记录模块版本的格式是:每行一个模块;格式为:模块名@@版本号,版本号支持~>前缀,不可带空格
    • 另外一个文件是模块名.podspec文件
    • 按照podspec文件要求的格式去修改版本号
  2. 使用脚本修改
    • 执行命令:./utils.sh [模块名] upgradedependency [依赖的模块名] [版本号]
    • 其中版本号能够为空
    • 例子:./utils.sh LoginModule upgradedependency AFNetworking 3.5.0
    • 例子:./utils.sh LoginModule upgradedependency AFNetworking
  3. 版本号可支持英文字符:a.b.c

3.3 如何在模块工程内使用Swift&OC混编

  1. 在module工程内建立OC的类文件及swift文件,假设OC类名为 TestOC,swift类名为TestSwift
  2. 让OC可以访问Swift类
    • 只须要在TestOC.m中添加import。例:#import "模块名/模块名-Swift.h"
    • 另外需注意的是,TestSwift类必须是public并继承自NSObject。
  3. 让Swift可以访问OC类
    • 在 [模块名].h 这个文件中引入你的头文件。例:#import "TestOC.h"
    • xcode - build phases - [模块名].h 文件必须在public区域

3.4 关于模块资源文件的获取

  1. 因为模块都是静态库,因此最终运行到app中后,每一个模块的资源文件(.xcassets, .xib, .png, .jpg, .jpeg, .gif, .txt, .plist, .bundle, .zip, .car)都是放到: "模块名.bundle"文件中的,而这个bundle在main bundle的根目录(这也是要求模块名防止重名的缘由之一)
  2. 因此获取图片可使用 UIImage.init(named: name, in: bundle, compatibleWith: nil) 方法
  3. 获取其余文件也须要指定bundle才能够
  4. 开发过程当中,获取任何资源都须要带bundle,不能直接使用相似 UIImage.init(named:String)这种方法,即便是在模块工程内部的代码也不行
  5. 须要注意的是,静态库的单元测试target是没法获取资源的

3.5 注意事项

  1. 模块名要防止重复,不但要防止同一个私有库重复,也要防止与其余pod repo内的模块重复
  2. 依赖库不可产生循环依赖,好比 A依赖B,B依赖C,C依赖A
  3. 每一个模块都有一个develop分支,develop分支的代码老是与最新的tag保持一致。执行push命令时,代码老是在develop分支上
  4. 开发期间(集成测试前)老是依赖本地模块,每次老是在集成测试前,才会执行push.sh脚本
  5. 若是当前的开发模块有修改,同时依赖的模块也有修改,则须要先push当前模块所依赖的模块,最后push当前模块。这时候可能须要使用 ./utils.sh [模块名] upgradedependency [依赖的模块名] [版本号] 命令修改模块所依赖的模块的版本号

--完--

  1. iOS应用模块化的思考及落地方案(一)模块的划分及模块化工做流程
  2. iOS应用模块化的思考及落地方案(二)模块化自动构建工具的使用
相关文章
相关标签/搜索