前幾天 Cocoapods 1.7.0 正式版發佈了,我最期待的一個功能是 Multiple Pod Projects,昨天順手就給接入了,項目解析和索引效率有了很是明顯的提高,過程當中踩了些坑,此次一塊兒把以前 debug 的經驗分享一下。git
以前 Cocoapods 會把每一個依賴做爲 target 放到 Pods 項目裏,但 xcodeproj 自己的編碼不太能適應這種狀況,在引入幾十個 pod 的狀況下,項目解析的效率會急劇降低。github
以我公司其中一個主項目爲例,Pods 項目的大小達到了 5.2 MB(這可都是純文本),在第一次打開項目,解析項目構建索引時,就能明顯聽到風扇開始狂轉,這個過程會持續好幾分鐘纔會結束。swift
Cocoapods 此次更新引入了一個 generate_multiple_pod_projects 的選項,可讓每一個依賴都做爲一個單獨的項目引入,大大增長了解析速度:xcode
開啓的方式很簡單,只要在 Podfile 里加入這一行就能夠了:ruby
install! 'cocoapods', generate_multiple_pod_projects: true
複製代碼
拆分後每一個項目的大小都差很少是 40 - 100 kb 左右:多線程
這個選項開啓以後的效果很是顯著,我在 Xcode 裏執行了 clean,以後 indexing 的過程在幾秒鐘裏就結束了,並且風扇也沒有狂轉。函數
至於爲何這樣能夠提高項目的解析速度,我大概看了一下 xcodeproj 的編碼,全部的 Item 都會按照類別存放到各自的 section 裏,最終在項目的結構樹裏會以引用的形式呈現。工具
因此文件引用查找的範圍是全部 Pod 引用庫的文件的集合,而每次索引的構建都至少會遍歷一次項目樹,這就會致使索引時間的暴增,除此以外單個龐大的項目解析也不利於多線程執行,拆分紅多個項目的話就能有效地解決這些問題。post
須要注意 install!
是個用來配置的函數,因爲以前我還開啓了另外一個選項,因此接入時是這麼作的:ui
install! 'cocoapods', generate_multiple_pod_projects: true
install! 'cocoapods', disable_input_output_paths: true
複製代碼
可是這麼作以後發現不生效,後來纔想起來 install!
是一個用來配置的函數,重複調用的話,只會以最後一次的調用爲準。因此應該在一次調用裏把它們都傳入進去:
install! 'cocoapods',
disable_input_output_paths: true,
generate_multiple_pod_projects: true
複製代碼
另外一個坑就是在 post_install
時,爲了一些版本的兼容,須要遍歷全部 target,調整一部分庫的 Swift 版本:
post_install do |installer|
swift_4_0_compatible = [ ... ]
swift_4_2_compatible = [ ... ]
installer.pod_targets.each do |t|
t.build_configurations.each do |c|
c.build_settings['SWIFT_VERSION'] = '4.0' if swift_4_0_compatible.include? t.name
c.build_settings['SWIFT_VERSION'] = '4.2' if swift_4_2_compatible.include? t.name
end
end
end
複製代碼
可是若是開啓了 generate_multiple_pod_projects
的話,因爲項目結構的變化,installer.pod_targets
就沒辦法得到全部 pods 引入的 target 了。
查了 Xcodeproj 和 Cocoapods 的文檔以後我都沒有獲得很好的解答,因此我就想用 xcodeproj 自己的接口去處理這件事情。
因爲 Podfile 本質上是 Ruby 腳本,因此這裏我一般會使用 Ruby 的 debugger 去操做,經過 Ruby 強大的自省能力,在 debugger 裏進行嘗試而後找到咱們須要的接口,開始以前咱們須要安裝一個 Ruby 的工具,步驟以下:
gem install pry
require 'pry'
binding.pry
語句就能夠了我在 post_install 裏插入了斷點,接着運行 pod install
,就看到斷點生效了:
Ruby 的自省能力很是強大,並且 pry 也基於此作了不少實用的功能,在這裏我直接輸入了 installer
回車,就能看到它全部屬性都被遞歸打印出來。
這裏面我找了一下以後,發現一個文檔裏沒有記錄的屬性,叫作 pod_target_subprojects
,包含了全部 Pods 的項目,彷佛能夠知足咱們的需求:
接着 Ctrl + d 退出 pry,回到 Podfile 修改便可:
post_install do |installer|
swift_4_0_compatible = [ ... ]
swift_4_2_compatible = [ ... ]
installer.pod_target_subprojects.flat_map { |p| p.targets }.each do |t|
t.build_configurations.each do |c|
c.build_settings['SWIFT_VERSION'] = '4.0' if swift_4_0_compatible.include? t.name
c.build_settings['SWIFT_VERSION'] = '4.2' if swift_4_2_compatible.include? t.name
end
end
end
複製代碼
最後 pod install
一下,打開 Xcode 查看對應的 target 的編譯設置,確實有效。
這裏介紹的 debug 方法在 fastlane 裏也適用,很是建議你們在編寫複雜腳本時先用 debugger 去提早踩坑。
用慣了 Ruby 的 debug 方式以後,回到 LLDB 感受體驗差了不少😂。
若是以爲文章還不錯的話能夠關注一下個人博客。