一、概述
距离上一篇iOS二进制编译方案(iOS如何提高10倍以上编译速度)已经快过去半年了,期间收到了很多来着小伙伴们的支持。cocoapods-imy-bin这套系统也在我司(美柚)跑满了上万条的打包记录,目前表现依然是很稳定。
鉴于目前市场上,Swift及Swift-OC混编项目流行,且Swift的编译项目过慢的问题,在业务繁忙之瑕,做了对Swift、Swift-OC项目的二进制组件化的支持。希望能给小伙伴们在iOS编译的问题上,提供帮助。
二、项目效果
直接上图看效果,多余的话就不多说了。本文实验Swift-OC-Demo地址,感兴趣的小伙伴们可以自行下载验证效果。
图一、Build tasks对比 图二、Build time对比图一、编译任务数,在未使用\使用二进制时,编译tasks是532\113个、113个tasks是除了Pods库外的一些其他文件、link、copy文件、sign等tasks,减少了80%的tasks。
图二、编译时间,在未使用\使用二进制时,编译时间是35.9s\17.8s个、17.8s是除了Pods库外的一些其他文件、link、copy文件、sign等时间,效率提升了2倍。
图三、美柚App 编译时间对比.png总体效率上,编译速度的提升是非常可观的,项目越大、性能提升越明显,在我司美柚APP项目上,编译提速可达13倍以上。(全量编译)
三、Cocoapods-imy-bin项目功能
自动化支持iOS项目组件二进制化:
- 无入侵、无感知、不影响现有业务,不影响现有代码框架、完全绿色产品~
- 轻量级,只要项目能编译通过就能使用,无视组件化、无视耦合
- 完全自动化,一键使用、无需手动操作
- 支持 使用与不使用
use_frameworks!
- 提供几个特色服务
- 少数支持swift项目二进制化编译的开源项目之一
四、Swift二进制化实现简介
目前Demo是Swift-OC 混编,同时支持纯Swift项目。OC-Demo在这,具体原理及详情请移步到 iOS如何提高10倍以上编译速度。
Swift二进制化原理其实也就那么回事,在pod的时候,全部自动转换成Framework
图四 图五、自动转换依赖二进制化组件五、Swift二进制化遇到的问题
1、Module compiled with Swift 5.1.3 cannot be imported by the Swift 5.2.2 compiler
解决:
1、配置Framework的Build Setting将“Build Libraries for Distribution”选项设置为 YES,否则Swift编译器不会生成必要的".swiftinterface文件,这是将来编译器能够加载旧库的关键。
2、如果机器不多的话,可以把xcode更新到统一的版本号
2、转换后的工程,在{Development Pods}下,OC引用Swift文件,找不到对应的类
image解决:(建议壳工程化,可以避免此问题)
image这个文件是混编时,系统生成的Swift文件对应的Objective-C的头文件,具体可以在Targets-->Build Settings-->Swift Compiler - General-->Objective-C Generated Interface Header Name进行配置,默认文件名是工程名-Swift.h,一般不做改动。
3、Podfile引用 use_frameworks! 与不引用 use_frameworks!的编译问题
找不到对应的头文件,这个头文件是xcode编译时自动生成的,在Products/Debug-iphonesimulator/lottie-ios/lottie-ios.framework/Headers 中,去掉use_frameworks!后就找不到了
image解决:在Header Search Paths 添加对应的文件引用
image4、Command PhaseScriptExecution failed with a nonzero exit code
image解决:cocopods1.8.4会出现此问题,升到1.9.1后就正常了
5、Masonry
, which do not define modules. To opt into those targets generating module maps (which is necessary to import them from Swift when building as static libraries), you may set use_modular_headers!
globally in your Podfile, or specify :modular_headers => true
for particular dependencies.
pod bin auto 的时候出现了
image解决:修改cocoapods插件相关代码,或者使用cocopods-imy-bin v0.3.11版本即可解决。
# setting modular_headers_for
if(target_definition && target_definition.use_modular_headers_hash.values.any?)
target_definition.use_modular_headers_hash.values.each do |f|
f.each { | pod_name| self.set_use_modular_headers_for_pod(pod_name, true) }
end
end
欢迎大家的加入,一起学习与探讨
作者简介
苏良锦,美柚 iOS 工程师,2019 年加入美柚。
网友评论