一文搞定Swift編譯慢的問題,還有全套開源,請看這裏!

一、概述

距離上一篇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項目組件二進制化:

  1. 無入侵、無感知、不影響現有業務,不影響現有代碼框架、完全綠色產品~
  2. 輕量級,只要項目能編譯通過就能使用,無視組件化、無視耦合
  3. 完全自動化,一鍵使用、無需手動操作
  4. 支持 使用與不使用 use_frameworks!
  5. 提供幾個特色服務
  6. 少數支持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
來源:掘金

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章