1. 背景
驾校一点通iOS项目是采用是cocoapods来管理组件的,又经过多年的组件化发展,目前组件已经达到了120+的数量。在这种组件规模下,主工程的打包时间也从最开始的几分钟增加到十几分钟(M1)、二十几分钟(Intel)。而且在频繁切换分支开发的场景下,每次编译的耗时成了制约团队效率的重要问题。
基于上述原因我调研了行业内编译提速的方案,发现或多或少存在着一些问题。
所以我结合自己的业务场景,抽象出了一些需求。开发出了一款使用简单,不改变cocoapods使用习惯,适用大部分iOS开发场景的cocoapods插件(cocoapods-jxedt)。
2. cocoapods-jxedt插件介绍
我们开发的插件叫做cocoapods-jxedt。是结合作者多年的iOS一线开发经验和复杂的业务场景,总结产出的一个支持pod组件二进制化的cocoapods插件。
开发者只需要简单的在Podfile文件中做一些简单配置,就可以完成组件二进制化的操作。本质是预编译源码为二进制,hook cocoapods
的执行过程,将源码依赖修改为二进制依赖,以提升编译速度。
使用本插件,只需要了解我们提供的插件配置参数,不需要你改变cocoapods的使用习惯,正常使用 pod install
和 pod update
命令。
插件的功能和亮点
- 支持pod使用library静态库的工程
- 支持framework和xcframework
- 支持clang module(支持swift、混编)
- 同时支持Debug和Release两个环境的二进制
- 非常简单的切换源码和二进制(不用清除pod文件夹)
- 兼容
#import "..."
和#import <...>
方式的头文件引用 - 提供快速修改头文件引用的命令,
pod jxedt headerfix
,快速支持使用use_frameworks!
- 支持静态库的resources中包含xib、xcdatamodeld格式文件的场景(这类文件需要编译)
- 支持二进制pod组件版本控制,支持非tag依赖的pod组件版本控制
- 支持组件二进制远程缓存(使用git仓库做二进制文件的缓存,不需要配置静态资源服务器)
- 支持二进制调试的功能
- 提供了许多提效的插件命令
- 不改变cocoapods的使用习惯,正常使用
pod install
和pod update
目前,本插件还未开源,但是我们已经发布gem到rubygems.org,可以使用gem来进行安装。你现在可以使用我们的Demo工程来体验一下插件。
在插件的开发过程中,我研读了许许多多优秀的二进制化的方案,也借鉴了各位前辈的一些思想,最终完成了这个支持大部分iOS开发场景的插件。在这里感谢这些开源作者,感谢各位的辛勤付出。
这些优秀的文章或插件有:
- cocoapods-binary
- cocoapods-binary-cache
- 火掌柜iOS端基于CocoaPods的组件二进制化实践
- iOS编译速度如何稳定提高10倍以上
- Pod二进制化(作业部落)
- 从预编译的角度理解Swift与Objective-C及混编机制
3. 插件的安装和使用
安装
$ gem install cocoapods-jxedt
使用
直接在Podfile中新增下面的方法就可以开启插件
use_frameworks! :linkage => :static
# use_modular_headers!
plugin 'cocoapods-jxedt'
options = {
'all_binary': true, # 所有组件开启binary
'keep_source_project': true, # 保留源码pod工程,所在目录`Pods-Source`
'excluded_pods': [], # 排除binary的组件名称
'framework_header_search_enabled': true, # 兼容头文件引用`#import "xxx.h"`
'configurations': ['Release'], # 支持的configurations ['Release', 'Debug']
'device_build_enabled': true, # 真机
'simulator_build_enabled': false # 模拟器
}
cocoapods_jxedt_config(options)
或者执行我们提供的命令
pod jxedt options
、
pod jxedt options --config
、
pod jxedt options --more-config
来获取插件的配置参数介绍和基础配置。
另外,也可以查看我们提供的Demo工程来尝试使用。
按照上面的配置参数配置好Podfile文件,就可以使用插件的功能了,现在快乐的去执行pod install
就可以了。
执行之后目录是这样的:
看到文章的这里,你应该已经可以正常使用我们提供的的插件了。
另外插件也提供了一些插件命令,是作者在实际开发中遇到问题的总结,感兴趣的话可以继续阅读,相信阅读完之后能加深对插件的认识。
4. 插件命令
我们总结了真实开发场景的一些问题,提供了一些操作的命令。主要是针对单工程而言,命令大部分都需要再Podfile所在目录执行。
4.1 options
插件的配置参数介绍。
通过此命令可以快速的了解本插件支持哪些配置参数以及每个配置参数的意义
pod jxedt options --help
获取使用插件的简单配置
pod jxedt options --config
4.2 headerfix
我们提供的快速修改头文件的命令,此命令也可以在不使用插件二进制功能的情况下使用。
具体而言:
- 假设你有自己的组件PodA,它依赖了AFNetworking和YYImage等三方组件
- 你在PodA中引用头文件的方式为
#import "AFNetworking.h"
、#import "YYImage.h"
,这种引用头文件的方式在使用library的时候cocoapods是支持的,但是如果你需要修改为use_frameworks!
或支持混编的时候这样的引用就存在问题了。 - 使用
pod jxedt headerfix
命令可以自动分析出组件的依赖,然后修改"AFNetworking.h"或<AFNetworking.h>这种头文件引用方式为#import <AFNetworking/AFNetworking.h>
,并且我们会输出修改日志,你也可以对比日志的修改内容来查看结果
查看headerfix命令介绍
pod jxedt headerfix --help
4.3 user
这个是我们提供的快速创建用户目录的一个命令。创建的目录为/Users/cocoapods-jxedt
。
该命令可以根据自己的需要决定是否使用,我们提供这个命令是来做二进制和源码链接调试的。
具体而言:
- 二进制源码调试可以运行的条件是:编译二进制时的源码所在路径存在,二进制断点时就可以跳转到对应的源码。
- 基于上面这种特性,如果想在多台电脑上都能调试源码,就要求多台电脑上都存在二进制编译时的路径和源码文件
- 一个团队中有很多同学进行开发,每个人的user目录都不尽相同,所以回到我们的命令的功能上,我们就是要保证每个人的电脑上都存在
/Users/cocoapods-jxedt
这个目录。这样,无论哪位开发者编译了二进制,编译时的源码路径都是相同的,二进制调试才能实现。 - 执行命令创建目录需要权限,在执行过程中可能需要你输入电脑密码,创建好目录后会把这个目录的权限改为777(任何user都可访问和修改)。
查看user命令介绍:
pod jxedt user --help
4.4 binary
binary是一个抽象的命令,是二进制操作的命令入口,它下面有许多子命令。
binary下的命令要求配置好插件(Podfile文件中配置好),二进制相关的操作会根据插件配置来执行。
查询binary命令
pod jxedt binary --help
4.4.1 build
编译源码组件为二进制。
- name参数为必要参数,指定编译某个组件。
- push、force-push参数是把编译结果推送到二进制git仓库,需要在插件配置中配置
- output-path参数是二进制结果的生成路径,默认在Podfile所在目录下的
Pod-Source/.command_build
文件夹下
pod jxedt binary build --help
4.4.2 clean
清除二进制。因为某些特殊情况需要清除已编译的二进制,可以执行此命令。
- name参数指的是删除某个组件
- local参数表示只操作本地缓存的组件,对工程而言,不操作git
- all参数表示删除所有的已编译二进制组件
pod jxedt binary clean --help
4.4.3 code
二进制链接源码,用于二进制调试。
两个参数:
- link,链接源码
- unlink,删除源码链接
pod jxedt binary code --help
4.4.4 fetch
拉取二进制git仓库缓存的二进制到本地,本身是一个 git pull
的操作,本地路径在 ~/.cocoapods-jxedt/xxx
。
pod jxedt binary fetch --help
4.4.5 push
推送本地的二进制组件到二进制git仓库。查看本地已经编译好的二进制文件,压缩成zip文件,名称以checksum值命名,推送到远程仓库。
- force-push参数表示如果远程存在相同校验和(checksum)的文件,强制推送
pod jxedt binary push --help
4.4.6 sourceProject
这个命令是生成当前二进制环境对应的源码工程。这个工程我们在每次pod install时都会生成,但是默认是不保留这个工程的,开发场景中切换为了二进制,而又需要查看源码时,可以通过这个命令恢复源码工程。
pod jxedt binary sourceProject --help
4.4.7 statistics
二进制组件使用情况的统计。可以通过此命令查看当前工程使用二进制的组件和详细介绍,如果有校验失败的二进制,会有报错信息。
pod jxedt binary statistics --help
5. 反馈
目前插件暂未开源,我们致力于解决iOS开发编译过程中的痛点,所以我们仍然期待你的反馈。
如果你有插件使用的问题或者有其他的疑惑,可以直接在我们提供的Demo工程下提交issue,我们看到了会尽快反馈。