一、概述
距離上一篇iOS二進制編譯方案(iOS如何提高10倍以上編譯速度)已經快過去半年了,期間收到了很多來着小夥伴們的支持。cocoapods-imy-bin這套系統也在我司(美柚)跑滿了上萬條的打包記錄,目前表現依然是很穩定。
鑑於目前市場上,Swift及Swift-OC混編項目流行,且Swift的編譯項目過慢的問題,在業務繁忙之瑕,做了對Swift、Swift-OC項目的二進制組件化的支持。希望能給小夥伴們在iOS編譯的問題上,提供幫助。
二、項目效果
我們Cocoapods-imy-bin項目,同時支持對純Swift、純Object-C、Swift-OC混編的二進制化。
直接上圖看效果,多餘的話就不多說了。本文實驗Swift-OC-Demo地址,感興趣的小夥伴們可以自行下載驗證效果。
圖一、Build tasks對比
作爲一個開發者,有一個學習的氛圍跟一個交流圈子特別重要,這是一個我的iOS交流羣:413038000,不管你是小白還是大牛歡迎入駐 ,分享BAT,阿里面試題、面試經驗,討論技術, 大家一起交流學習成長!
以下資料在羣文件可自行下載!
圖二、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 編譯時間對比
總體效率上,編譯速度的提升是非常可觀的,項目越大、性能提升越明顯,在我司美柚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文件,找不到對應的類
解決:(建議殼工程化,可以避免此問題)
這個文件是混編時,系統生成的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!後就找不到了
解決:在Header Search Paths 添加對應的文件引用
4、Command PhaseScriptExecution failed with a nonzero exit code
解決: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 的時候出現了
解決:修改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 年加入美柚。
作爲一個開發者,有一個學習的氛圍跟一個交流圈子特別重要,這是一個我的iOS交流羣:413038000,不管你是小白還是大牛歡迎入駐 ,分享BAT,阿里面試題、面試經驗,討論技術, 大家一起交流學習成長!
以下資料在羣文件可自行下載!
作者:Mr_Coder
鏈接:https://juejin.cn/post/6890419459639476237
來源:掘金