Swift編譯慢?請看這里,全套開源

作者 | 蘇良錦,美柚 iOS 工程師,2019 年加入美柚。
來源 | 掘金,點(diǎn)擊閱讀原文查看作者更多文章
一、概述
距離上一篇iOS二進(jìn)制編譯方案(iOS如何提高10倍以上編譯速度)已經(jīng)快過去半年了,期間收到了很多來著小伙伴們的支持。cocoapods-imy-bin這套系統(tǒng)也在我司(美柚)跑滿了上萬條的打包記錄,目前表現(xiàn)依然是很穩(wěn)定。
鑒于目前市場上,Swift及Swift-OC混編項(xiàng)目流行,且Swift的編譯項(xiàng)目過慢的問題,在業(yè)務(wù)繁忙之瑕,做了對Swift、Swift-OC項(xiàng)目的二進(jìn)制組件化的支持。希望能給小伙伴們在iOS編譯的問題上,提供幫助。
二、項(xiàng)目效果
我們Cocoapods-imy-bin項(xiàng)目,同時支持對純Swift、純Object-C、Swift-OC混編的二進(jìn)制化。
直接上圖看效果,多余的話就不多說了。本文實(shí)驗(yàn)Swift-OC-Demo地址,感興趣的小伙伴們可以自行下載驗(yàn)證效果。

圖一、Build tasks對比

圖二、Build time對比
圖一、編譯任務(wù)數(shù),在未使用\使用二進(jìn)制時,編譯tasks是532\113個、113個tasks是除了Pods庫外的一些其他文件、link、copy文件、sign等tasks,減少了80%的tasks。
圖二、編譯時間,在未使用\使用二進(jìn)制時,編譯時間是35.9s\17.8s個、17.8s是除了Pods庫外的一些其他文件、link、copy文件、sign等時間,效率提升了2倍。

圖三、美柚App 編譯時間對比
總體效率上,編譯速度的提升是非??捎^的,項(xiàng)目越大、性能提升越明顯,在我司美柚APP項(xiàng)目上,編譯提速可達(dá)13倍以上。(全量編譯)
三、Cocoapods-imy-bin項(xiàng)目功能
自動化支持iOS項(xiàng)目組件二進(jìn)制化:
無入侵、無感知、不影響現(xiàn)有業(yè)務(wù),不影響現(xiàn)有代碼框架、完全綠色產(chǎn)品~
輕量級,只要項(xiàng)目能編譯通過就能使用,無視組件化、無視耦合
完全自動化,一鍵使用、無需手動操作
支持 使用與不使用 use_frameworks!
提供幾個特色服務(wù)
少數(shù)支持swift項(xiàng)目二進(jìn)制化編譯的開源項(xiàng)目之一
四、Swift二進(jìn)制化實(shí)現(xiàn)簡介
目前Demo是Swift-OC 混編,同時支持純Swift項(xiàng)目。OC-Demo在這,具體原理及詳情請移步到 iOS如何提高10倍以上編譯速度。
Swift二進(jìn)制化原理其實(shí)也就那么回事,在pod的時候,全部自動轉(zhuǎn)換成Framework

圖四

圖五、自動轉(zhuǎn)換依賴二進(jìn)制化組件
五、Swift二進(jìn)制化遇到的問題
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”選項(xiàng)設(shè)置為 YES,否則Swift編譯器不會生成必要的".swiftinterface文件,這是將來編譯器能夠加載舊庫的關(guān)鍵。
2、如果機(jī)器不多的話,可以把xcode更新到統(tǒng)一的版本號
2、轉(zhuǎn)換后的工程,在{Development Pods}下,OC引用Swift文件,找不到對應(yīng)的類

解決:(建議殼工程化,可以避免此問題)
這個文件是混編時,系統(tǒng)生成的Swift文件對應(yīng)的Objective-C的頭文件,具體可以在Targets-->Build Settings-->Swift Compiler - General-->Objective-C Generated Interface Header Name進(jìn)行配置,默認(rèn)文件名是工程名-Swift.h,一般不做改動。

3、Podfile引用 use_frameworks! 與不引用 use_frameworks!的編譯問題
找不到對應(yīng)的頭文件,這個頭文件是xcode編譯時自動生成的,在Products/Debug-iphonesimulator/lottie-ios/lottie-ios.framework/Headers 中,去掉use_frameworks!后就找不到了

解決:在Header Search Paths 添加對應(yīng)的文件引用

4、Command PhaseScriptExecution failed with a nonzero exit code

解決:cocopods1.8.4會出現(xiàn)此問題,升到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 的時候出現(xiàn)了

解決:修改cocoapods插件相關(guān)代碼,或者使用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
歡迎大家的加入,一起學(xué)習(xí)與探討
