Cocoapods 的功能非常强大,除了常规的第三方 pod 管理,还有很多其他强大的功能。Cocoapods 应用系列将列列举我在工作中遇到的应用,更多细节请阅读 cocoapods 文档或源码。
背景
最近在搞工程模块解耦的事情,为了方便同学们更好地开展自己的工作,我需要这么一个工具,功能包括:
- 可以分析出某个目标模块对其他模块的依赖关系,包括引用级别以及模块级别
- 可以检查当前模块是否对我们提前划分好的层次架构的上层模块的东西,如果有,在 build 的时候,当前模块对应的 target 直接编译 error
显然,这个脚本需要放在各模块编译阶段执行。那,如何自动给所有待解耦模块增加这么一个在 build 时运行的脚本呢?于是引出了本文。
探索
最容易想到的就是, Xcode 中 target 的 Build Phase 配置中有一个 Run Script 。
cocoapods 管理的工程一般都包含两个工程:主工程和Pods工程。而经过 Cocoapods 改造后的本地 Pod 集都在这个 Pods 下管理,Cocoapods 会为每一个 local pod 生成对应的 target。而我们要的就是,为我们关心的 target 增加一个上面提到的脚本。
显然,我们需要探索一下 Cocoapods 的 Hook 功能了。
按照上面功能的描述,似乎 pre install 阶段和 post install 阶段执行都 ok!当时,pre install 拿不到每一个 target,而后者是可以的。
那,剩下的问题就清晰了,cocoapods 中的 target 是否有这样的 api,允许我给当前 target 添加一个自定义脚本呢?通过 byebug 调试工具发现 target 真的包含 build phase 的方法:
哇,真的有,而且还有很多,基本涵盖了Xcode 中 Build Phase 下的所有功能。其中,new_shell_script_build_phase 这个方法引起了我的注意,之后就是尝试调用。
首先肯定是找到 Cocoapods 源码查看这个 api 的描述是啥:
描述很清晰,在源码中也找到了一处应用实例:
使用还是比较简单的,于是新建一个 XcodeDemo 工程尝试下:
至于,你想执行什么脚本,做什么事,那就自由发挥了,想象空间还是很大的。
Sentence
post_install do |installer|
installer.pods_project.targets.each do |target|
phase = target.new_shell_script_build_phase("Custom Script")
phase.shell_script = "echo Hello"
target.build_configurations.each do |config|
end
end
end
最后,Enjoy yourself!