天天看點

iOS開發體驗優化方案iOS開發體驗存在的問題iOS環境搭建切分支後APP打包速度問題總結

iOS開發體驗優化方案iOS開發體驗存在的問題iOS環境搭建切分支後APP打包速度問題總結

iOS開發體驗存在的問題

▐ 開發環境搭建難

開發環境依賴特定軟體版本,配置複雜

閑魚iOS工程不僅依賴XCode,還依賴了taobaoenv 1.2.0和cocoapods 1.2.0這兩個包管理工具。根據大家的經驗,這兩個工具在ruby2.3.x時,問題較少。特定軟體版本,系統自帶軟體版本沖突,環境變量設定等等一些列的操作步驟導緻環境搭建複雜,需要求助iOS開發同學才能搞定。

維護難

Mac系統更新後,cocoapod容易出現問題,不得不重新搭建開發環境。具體原因也是多種多樣:系統環境變量變了,導緻找不到特定版本ruby;ruby随系統更新導緻cocoapod不能用,需要重新安裝;Gem版本問題;Ruby源問題等等。這也導緻許多開發同學不敢輕易的去更新系統,無法及時體驗到新系統的特性。

Pod依賴下載下傳量大

由于cocoapod本身的工作原理,pod更新下載下傳工程依賴時,會下載下傳各個版本的檔案資訊,總量特别大。以閑魚iOS工程為例,總共需要下載下傳近20G的緩存檔案,而且大部分都是幾K的小檔案,下載下傳時間可能會持續十幾個小時,導緻新環境搭建到初次體驗時間跨度非常久。

▐ 切分後APP打包慢

當開發同學在多個分支/版本開發的時候,時常需要切換分支開發調試和bugfix。但是切換分支之後,整個iOS工程打包時間在30-40分鐘左右。有時候為了修複一個版本的bug,不得不切換分支,然後重新打包調試。修複和驗證bug可能隻需要五分鐘,打包卻用了30多分鐘,投入産出不成比例。

為了解決這些存在的問題,我們進行了一些列的探索,跟大家一起分享下,也歡迎有更好的解決方案出現。

iOS環境搭建

虛拟化技術的不斷發展,為我們統一端側開發環境提供了新思路,我們設想如果iOS開發環境能夠跟Mac解耦,且可以移植,大家可以輕松複用,那麼第一二個問題就迎刃而解了。為此我們做了幾個嘗試:

▐ 虛拟機方案

在MacOS本地搭建虛拟機,内裝MacOS系統。在虛拟機内搭建iOS開發環境,然後通過虛拟機鏡像copy實作iOS開發環境移植,解決環境搭建難題。

iOS開發體驗優化方案iOS開發體驗存在的問題iOS環境搭建切分支後APP打包速度問題總結

這個方案存在以下幾個問題:

性能問題:iOS的編譯過程是一個IO密集型和CPU密集型操作,虛拟機通過虛拟HOST系統的磁盤和CPU,性能會大打折扣,導緻編譯時間變長,影響開發體驗。

安全問題:在Mac工作機安裝虛拟機,需要通過公司安全稽核。

黑蘋果問題:虛拟機内的Mac系統是沒有經過授權的,會帶來盜版侵權風險。

虛拟機是比較重的虛拟化技術,是以我們轉向了更加輕量化的docker技術。

▐ 完全Docker化

将iOS開發依賴的軟體和環境變量全部docker化。通過docker鏡像實作iOS開發環境的移植。對于cocoapod, taobaoenv等ruby類工具,鑒于ruby的跨平台特性,可以很友善的遷移到docker内。但是對于強依賴MacOS的XCode,我們嘗試用Facebook出品的xcbuild替代。這是一款相容xcodebuild的編譯工具,網上也确實有網友用這個軟體搭建iOS編譯環境。

iOS開發體驗優化方案iOS開發體驗存在的問題iOS環境搭建切分支後APP打包速度問題總結

Xcbuild跟Xcodebuild的相容性無法評估

xcode更新後,xcbuild跟進更新相容的一段時間内,隻能回退到原來的開發方案,來回切換開發環境,體驗差。

上面兩個方案都沒有很好的解決iOS開發環境移植和解耦的問題,但是在完全docker化的嘗試中,我們發現最複雜的cocoapod和ruby安裝配置部分是能夠docker化的,xcode安裝後并不需要特殊的配置,是以我們設計實作了一個折中方案:Host内開發(部分docker化)

▐ Host内開發(部分docker化)

本方案中:開發編譯調試工作仍然在MacOS本地,使用xcode; 而将cocoapod和taobaoenv相關的軟體和環境變量配置等docker化。這樣既遵循了開發同學一貫的開發體驗,又兼顧了開發環境的可移植問題。

iOS開發體驗優化方案iOS開發體驗存在的問題iOS環境搭建切分支後APP打包速度問題總結

為了能夠讓Docker内cocoapod拉取的依賴檔案和生成的pod工程能被本地的XCode識别,我們将本地pod緩存目錄挂載到docker,這樣Pod拉取的依賴既能在docker内更新,也能在MacOS中被XCode通路,具體如下圖(統一程式設計平面端+Faas軟體架構圖):

iOS開發體驗優化方案iOS開發體驗存在的問題iOS環境搭建切分支後APP打包速度問題總結

這樣既做到了簡化開發環境搭建的複雜度,友善了想嘗試iOS開發的同學快速搭建環境,還能給開發同學無差别體驗。而且通過這個方案,我們的iOS開發環境可以友善的在各個同學的開發環境中遷移,而且也可以統一進行更新改造。

本方案将Pod相關的依賴遷移到了Docker中,與MacOS解耦,是以iOS開發同學可以自由更新Mac系統,不用擔心開發環境被破壞,解決了維護難的問題。

為了解決新搭建的環境需要大量拉取pod依賴的問題,我們将pod的本地中間檔案上傳到OSS雲盤(上圖藍色OSS雲盤),開發同學隻需要一次性下載下傳壓縮包并解壓到本地,然後增量更新就可以了。

切分支後APP打包速度問題

用戶端開發同學經常需要在多個分支(版本)上面開發業務,且時常需要來回切換進行業務開發和問題定位。這帶來的一個問題是:當開發同學從A分支切換到B分支的時候,需要重新打包APP,整個過程大概需要30-40分鐘左右。

在分析了閑魚iOS工程打包過程後,我們将耗時鎖定在兩個階段:Pod操作和XCode編譯。打包速度優化也将分為兩個階段進行:

▐ Pod操作加速

Pod install/update主要的工作是讀取Podfile,進行依賴版本控制和沖突解決,并生成Pod工程。生成的相關檔案存儲在Pods目錄和Pods.xcodeproj中。當切換回之前分支時,Podfile經常是不會發生變化的,是以重新生成pod工程實屬浪費。

經過測試,如果我們将這些中間檔案儲存起來,多次切換分支後,這些中間檔案仍然能夠還原之前的Pod工程,進而避免切分支後重新生成Pod工程的步驟,省去10分鐘左右的開銷。

▐ XCode編譯速度優化

對于XCode編譯速度優化,網上有很多方案,大緻可以分為三類:

Cocopods依賴編譯加速:

比如cocoapods-packager,它可以将pod依賴打包成static library,IOS工程以靜态庫的形式引入pod依賴,省去重複編譯的時間。

但是這個方案也存在一些問題;私有庫和第三方庫更新很麻煩,每次都需要重新打包靜态庫,并上傳到代碼倉庫;且很難調試源碼

分布式編譯:比如distcc

分布式編譯的原理是将需要編譯的檔案分散到編譯叢集的其他機器上編譯,然後将編譯好的二進制檔案傳回。本地編譯器再将這些二進制檔案連結在一起。分布式編譯對于大工程提速明顯,但是對于小工程,反而會拖累編譯速度。

緩存編譯的中間結果:CCache,BUCK

更為廣泛的加速方案是緩存編譯的中間結果,比如CCache,Buck等,這些方案,網上有詳細的資料,不再一一贅述。但是引入這些方案,都需要對目前的iOS工程進行改造,甚至需要改變使用者的開發習慣,是以不符合我們的要求。但是緩存中間編譯結果的方案給我們提供了一些啟發:

我們知道XCode是具有增量編譯能力的,這其實也是利用了上一次編譯的中間産物,本地再次編譯的時候,如果發現檔案沒有變化,則忽略這個檔案,如果源碼檔案時間戳更新了,那麼就重新編譯這個檔案,因為每次變化的源碼都是少量的,這樣就可以達到加快編譯速度的目的。

對于閑魚iOS工程,如果我們在切分支之前儲存目前iOS分支編譯的中間産物,然後在切換回目前分支的時候,恢複之前儲存的中間産物,那麼是不是就可以觸發XCode增量編譯了呢?事實确實如此。

iOS開發體驗優化方案iOS開發體驗存在的問題iOS環境搭建切分支後APP打包速度問題總結

具體方案:

1、在切分之前緩存目前分支的Pods Project, Flutter Project以及編譯的中間産物,Podfile.lock, linkmap等等相關檔案。

2、切換分支

3、恢複新分支之前緩存的中間産物

4、重新打包iOS APP。

通過這兩步優化,我們将閑魚iOS工程切分支後的打包時間由原來的30-40分鐘降低到五分鐘以内,效率提升近六倍。

總結

iOS環境搭建中複雜和耗時的步驟,通過docker鏡像和緩存優化後,搭建的難度大大降低,iOS新手也基本可以在三小時内搞定。

iOS開發體驗優化方案iOS開發體驗存在的問題iOS環境搭建切分支後APP打包速度問題總結

同時,通過緩存和複用打包過程産生的中間産物,切換分支後的打包耗時控制在五分鐘内,降低為原來的六分之一,提升了開發效率。

關注「淘系技術」微信公衆号,一個有溫度有内容的技術社群~

iOS開發體驗優化方案iOS開發體驗存在的問題iOS環境搭建切分支後APP打包速度問題總結

繼續閱讀