玩转CocoaPods
摘要: 作者:阿里-移動云-大前端 CocoaPods作為iOS的依賴管理工具,已然成為iOS開發的標準工具(官方給出的數據,超過42W個庫和300W個App使用了CocoaPods)。 本篇文章,非講述CocoaPods的教學文章,而是圍繞使用CocoaPods的兩個主題:依賴管理和Pod庫發布,講述些易忽略、混淆的關鍵點和不為熟知的用法。
點此查看原文:http://click.aliyun.com/m/41093/
作者:阿里-移動云-大前端
CocoaPods作為iOS的依賴管理工具,已然成為iOS開發的標準工具(官方給出的數據,超過42W個庫和300W個App使用了CocoaPods)。
本篇文章,非講述CocoaPods的教學文章,而是圍繞使用CocoaPods的兩個主題:依賴管理和Pod庫發布,講述些易忽略、混淆的關鍵點和不為熟知的用法。
執行pod env,可查看本地環境:
CocoaPods : 1.2.0Ruby : ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-darwin15]RubyGems : 2.5.1Host : Mac OS X 10.13.2 (17C88)Xcode : 9.2 (9C40b)Git : git version 2.14.3 (Apple Git-98)1. 依賴管理
1.1 Podfile
Podfile是一個說明文件,描述一個或多個Xcode工程Target的依賴庫,類似于Maven管理依賴的pom.xml文件。
Podfile可以很簡單,也可以很復雜。
依賴版本號
依賴最新版本,不指定版本號:
pod 'TestSDK'依賴指定版本,明確寫明版本號:
pod 'TestSDK', '1.0'使用邏輯運算符:
'> 1.0',版本號大于1.0。 '>= 1.0',版本號大于等于1.0。 '< 1.0',版本號小于1.0。 '<= 1.0',版本號小于等于1.0。使用optimistic operator (~>):
'~> 1.0.1',版本號范圍:1.0.1 <= version < 1.1 '~> 1.0',版本號范圍:1.0 <= version < 2.0 '~> 0',版本號范圍:0 <= version,無意義實際使用時,可根據項目需求,靈活配置依賴版本號。
Hook
Podfile中可配置鉤子函數,在依賴庫安裝過程中會被調用。主要有兩個Hook函數:pre_install和post_install,接收的參數為:Pod::Installer,分別對應Pods工程安裝前和安裝后。
pre_install配置示例如下:
pre_install do |installer|puts '[Test] - pre_install here' endpost_install配置示例如下,Pods工程安裝后,讀取打印iOS deploy target默認配置,并將其修改為8.0。
post_install do |installer|puts '[Test] - post_install here'installer.pods_project.targets.each do |target|target.build_configurations.each do |config|puts "[Test] - config:" + config.name + ", deploy target: " + config.build_settings['IPHONEOS_DEPLOYMENT_TARGET']config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '8.0'endend end1.2 pod install vs. pod update
Podfile.lock
該文件用來記錄和追蹤生成的Pod版本。
pod install
每次執行pod install,都會重新下載并安裝pods。
pods的版本號從Podfile.lock文件中獲取:
有記錄的pods,直接下載安裝該記錄版本號的pods,不檢查對應pods是否有更新;(已經安裝的pods不會更新其版本)
無記錄的pods,查找下載并安裝滿足Podfile中指定版本號條件的pods。
pod update
完整命令為:pod update [PODNAME],執行命令后,CocoaPods會無視Podfile.lock鎖定的版本號,查找并更新到,滿足Podfile中指定版本號條件的最新版本pods;若沒有指定PODNAME,默認更新Podfile中全部pods。
pod outdated
滿足Podfile中指定版本號條件下,列出比Podfile.lock中記錄鎖定的版本號新的pods。
實際執行pod update命令時,更新的pods即為執行pod outdated列出的pods。
建議用法
工程首次執行pod install或pod update,執行效果一致。
需要安裝新添加pod,建議執行pod install或pod update [NEW_POD],已安裝的其他pods版本不變,否則可能由于版本更新的不確定性引起適配問題。
明確更新某pod版本時,執行pod update [PODNAME],明確更新全部pods版本時,執行pod update。
1.3 pod cache
pod cache list [NAME]可列出本地pods緩存記錄,執行pod install或pod update時,若命中緩存記錄,則直接從本地拉取。
pod cache clean [NAME]刪除本地pods緩存記錄。
執行pod cache clean –all,刪除全部緩存記錄。
例:從私有CocoaPods倉庫拉取TestSDK v1.0.1,該記錄添加到本地緩存;由于某些原因TestSDK使用同樣的版本號v1.0.1做了覆蓋發布,可以先執行pod cache clean TestSDK,然后再執行pod update,保證拉取到最新版本的v1.0.1 SDK文件。
2. Pod庫發布
CocoaPods除了做依賴管理外,也會將自實現的pod庫上傳到公共倉庫/私有倉庫。
2.1 podspec
podspec文件,即Pod Specification(Pod描述文件),描述指定版本的pod庫信息,包括:pod庫源碼地址、文件列表、配置信息、描述信息等。
執行pod spec create,可創建生成.podspec文件,其為Ruby語法格式,修改后如下,例:
Pod::Spec.new do |spec|spec.name = 'Reachability'spec.version = '3.1.0'spec.license = { :type => 'BSD' }spec.homepage = 'https://github.com/tonymillion/Reachability'spec.authors = { 'Tony Million' => 'tonymillion@gmail.com' }spec.summary = 'ARC and GCD Compatible Reachability Class for iOS and OS X.'spec.source = { :git => 'https://github.com/tonymillion/Reachability.git', :tag => 'v3.1.0' }spec.source_files = 'Reachability.{h,m}'spec.framework = 'SystemConfiguration' end執行pod ipc spec xx.podspec,可將.podspec文件內容從Ruby轉換為json格式:
{"name": "Reachability","version": "3.1.0","license": {"type": "BSD"},"homepage": "https://github.com/tonymillion/Reachability","authors": {"Tony Million": "tonymillion@gmail.com"},"summary": "ARC and GCD Compatible Reachability Class for iOS and OS X.","source": {"git": "https://github.com/tonymillion/Reachability.git","tag": "v3.1.0"},"source_files": "Reachability.{h,m}","frameworks": "SystemConfiguration" }2.2 私有倉庫Push
CocoaPods倉庫本質上是Git倉庫,倉庫里存儲的是各pod庫所有版本的.podspec或.podspec.json描述文件。
pod庫上傳,即對應Git倉庫的commit提交。
Pod庫上傳到公共倉庫,即向 公共Git倉庫 提交commit。
因此,CocoaPods私有倉庫的搭建,只需再準備一個Github/Gitlab倉庫;具體搭建流程不再描述,可參考官網教程:CocoaPods - Private Pods。
執行pod repo push REPO [NAME.podspec]上傳Pod庫到私有倉庫,REPO為私有倉庫在本地的倉庫名。
準備上傳的Pod庫,如果對其他pod庫有依賴,需要在.podspec文件中聲明dependency;同時執行pod repo push命令時,添加--source參數,聲明依賴要查找的倉庫地址;支持配置多個倉庫地址,以,分隔。
例:
# 準備上傳TestSDK到私有倉庫PrivateSpec,倉庫Git坐標:git@github.com/xx/xx-specs.git # TestSDK依賴ASDK和BSDK,其中ASDK位于公共master倉庫,BSDK位于私有倉庫 # 上傳TestSDK時執行命令如下: pod repo push PrivateSpec TestSDK.podspec --verbose --allow-warnings --source=git@github.com/xx/xx-specs.git,git@github.com:CocoaPods/Specs.git2.3 依賴沖突
如果只從CocoaPods master倉庫拉取Pods,則不會有依賴沖突問題。依賴問題是由于引入三方私有CocoaPods倉庫導致的。
首先來看pods依賴傳遞問題。
Pods依賴傳遞
假設TestSDK依賴ASDK和BSDK,工程引入TestSDK后,執行pod install 或 pod update,會將TestSDK、ASDK和BSDK一并拉取下來,這種可認為是依賴傳遞。
Pods依賴傳遞版本號管理
假設有依賴關系如下,TestSDK使用時,ASDK必須集成1.0.1版本,CSDK和ASDK(1.0.2)不能兼容。
TestSDK(1.0.2)
ASDK(1.0.2)
BSDK(1.0.2)
CSDK(1.0.1)
ASDK(1.0.1)
按下面的依賴配置,拉取下來的SDK版本如下,存在CSDK和ASDK不兼容問題。
TestSDK(1.0.2)
ASDK(1.0.2)
BSDK(1.0.2)
CSDK(1.0.1)
此時,需要顯式指定ASDK版本號,拉取下來SDK版本如下:
TestSDK(1.0.2)
ASDK(1.0.1)
BSDK(1.0.2)
CSDK(1.0.1)
依賴沖突問題
存在于同時集成master公共倉庫和私有倉庫時,或集成多個私有倉庫時。
假設有兩個私有倉庫PrivateSpec1和PrivateSpec2,有SDK依賴關系如下,其中ASDK1和ASDK2是同一SDK的不同Pod封裝。
PrivateSpec1:
TestSDK1(1.0.0)
ASDK1(1.0.0)
PrivateSpec2:
TestSDK2(1.0.1)
ASDK2(1.0.1)
若同時依賴PrivateSpec1中的TestSDK1和PrivateSpec2中的TestSDK2,則ASDK1(1.0.0)和ASDK2(1.0.1)會沖突。
若Pods依賴支持類似Maven依賴的exclude,將ASDK1或ASDK2其中之一exclude,可解決該問題,但CocoaPods并不支持類似操作。
方法1,可手動集成TestSDK1或TestSDK2,將ASDK1或ASDK2刪除。
方法2,仍通過Pods集成,但ASDK1和ASDK2必須修改為同一Pod標識,集成時顯式指定ASDK版本號。
總結
以上是生活随笔為你收集整理的玩转CocoaPods的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 阿里云SDK再升级,宣布支持C++语言
- 下一篇: 全链路压测一招搞定,阿里云性能测试铂金版