CocoaPods最佳實踐探討

jopen 9年前發布 | 26K 次閱讀 CocoaPods iOS開發 移動開發
近期在項目中首次使用了CocoaPods。從軟件工程的角度來看,我對目前常見的CocoaPods使用方法有些意見,建議做一些改進。先說一下我建議的最佳實踐,后面再分析為什么要這樣做。并且希望大家根據自己公司的情況,討論一下這幾項建議是否合理,一起搞出一份真正的“最佳實踐”。

CocoaPods的常見使用方法參見唐巧的文章《用CocoaPods做iOS程序的依賴管理》。在他的基礎上,我提出幾條補充。

1. CocoaPods生成的Pods目錄*不*加入.gitignore,也就是說,第三方庫的源碼或binary要和產品代碼一起,提交到公司內部的版本控制系統上。每次修改Podfile并執行pod update后,把Podfile、Podfile.lock、Pods目錄下的改動一并簽入。
2. 保證在任何時候只簽出一次代碼就能直接編譯執行,不需要執行pod命令,甚至可以不裝CocoaPods就能參與開發。
3. Podfile里所有的庫使用精確版本號,不使用任何’~> 1.0', ‘>= 1.0'之類的版本號語法,只使用精確的版本號如'1.3.2'。
4. 在項目開發過程中,可以每隔一段時間使用pod outdated命令手動檢查各第三方庫是否有更新。如果發現某個庫有新版本,去第三方庫主頁查看更新記錄,并對版本變動做評估。如果確認有必要更新到最新版本,則修改Podfile里的版本號到最新版本,執行pod update。
5. 如果兩個人同時修改了Podfile,第二個人git pull后發現有conflict,resolve順序是:不動其他文件,先手動resolve Podfile的沖突;然后執行pod update;如果仍有沖突,可以用git reset把Podfile.lock和Pods目錄恢復原狀,再次執行pod update。此時應該沒有pod相關的沖突了。

------------------------------------

以下分析常見CocoaPods用法的問題,首先看CocoaPods官網上的示例Podfile。

source 'https://github.com/CocoaPods/Specs.git'
pod 'AFNetworking', '~> 1.0'

這兩行的含義是,使用github上的pods spec,安裝AFNetworking 1.x系列最新的那個版本;如果AFNetworking還依賴于其他庫,自動安裝合適的版本。

假設現在我們的項目中要用到第三方庫XYZ,開發流程大致如下:
1. 項目創建者張三在自己機器上安裝好CocoaPods。
2. 張三執行pod init,在Podfile里添加代碼 pod 'XYZ', '~> 1.0'。執行pod install,把Podfile和Podfile.lock簽入代碼管理,Pods目錄添加到.gitignore。
3. 項目開發人員李四安裝好CocoaPods。
4. 李四簽出代碼,編譯,發現pod報錯。于是執行pod install后,重新編譯通過。

這樣的CocoaPods使用方法可能引發很多異常情況。考慮第一類場景:
1. Github突然被盾了(曾經發生過)、或公司的外網出口掛了,李四無法成功執行pod install,因此只能眼巴巴的看著項目代碼,無法編譯。此時張三說,把我本地的Pods目錄都拷給你一份吧,雖然這樣拷來拷去容易出錯,但暫時先這樣臨時解決吧。
2. Github突然被盾了,公司的持續集成服務器上無法執行pod install,也沒法給服務器拷一份Pods目錄。于是連續多天無法用持續集成。
3. XYZ開發者在修改代碼時,從git上刪除了最新版本的tag,并重新加tag到另一次commit上。于是張三和李四得到的XYZ代碼是不同的。(雖然AFNetworking開發者很有經驗,不太可能出這種錯,但其他小的第三方庫就不一定了。)
4. 五年后,早就沒人使用古老的iOS 7了。XYZ開發者認為該庫是針對iOS 7的,技術已經太陳舊,于是從Github上刪除了該項目。(還好我們三年前就不再用這個庫了。)但某一天公司有個新項目,想參考以前的代碼。當打開代碼執行pod install時,發現Github上已經沒有XYZ庫了。

以上情況可以歸結為:你的代碼是否可用嚴重依賴于別人。你從公司的版本控制系統上獲取的代碼不能直接編譯,還依賴于世界各地很多其他人是否正確配置了他們的代碼,還依賴于Github等git服務商是否可用,等等。在極端情況下,會有災難性后果。

再看第二類場景:
5. 在我們項目的開發過程中,XYZ最新版本是1.4。一年后,我們重新打開舊的項目代碼,執行pod install,獲取到XYZ 1.x系列的最新版本1.7版。在XYZ 1.4到1.7版本之間,改變了一些接口和實現,我們的項目代碼很有可能無法編譯,或無法正確執行。

這里的問題是:常見的版本號寫法'~> 1.0’會在pod install或pod update時檢查版本更新,隨時將第三方庫升級到1.x系列的最新版本。對正在開發的項目來說,經常升級第三方庫是可以的。但對已經發布的產品代碼,這個變動是不可接受的。已發布的版本必須要有一份固定不變的代碼,否則配置管理就失去了意義。

還有第三類場景:
6. 張三的CocoaPods安裝的很早,和李四機器上的不是同一版本。這兩個版本的CocoaPods對依賴規則的resolve算法不同,因此李四 pod install失敗,無法下載到和張三相同的第三方庫代碼。這是真事,兩周前我們剛剛遇到了,后來解決方法是所有人都強制安裝某個舊版本的 CocoaPods。

這里的問題是:CocoaPods作為開發工具鏈中重要的一環,它的質量是否有保證?CocoaPods不是蘋果官方的工具,也不是像git那樣由極富經驗的人組織設計開發,我們能否信任它的版本兼容性?具體來說,即不管用什么版本的CocoaPods,pod install后得到基本相同的第三方庫。我們看到最近已經出了一個bug,如果時間再長點,三年后的CocoaPods會不會跟今天有較大差異?
對這個問題的一個解決方法是要求所有項目成員安裝相同版本的CocoaPods,甚至安裝相同版本的Ruby。但一個人需要同時參與多個項目的怎么辦?問題的根源還是沒變。

------------------------------------

基于以上分析,我提議的“最佳實踐”解決了以下問題。
* Pods目錄簽入到版本控制系統,使產品代碼沒有外部依賴,不管什么時候都能從公司內網獲取一份可直接運行的代碼。
* 已發布版本的產品代碼永久固定,不會隨時間而變化,方便追蹤問題和存檔。
* 不要求項目成員裝同樣版本的CocoaPods,甚至可以不裝CocoaPods。降低測試、設計人員使用代碼的難度,也避免了CocoaPods本身兼容性引起的問題。

來自:http://weibo.com/p/1001603800875490492754
 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!