摘要: >> 作者:阿里-移動云-大前端 CocoaPods作為iOS的依賴管理工具,已然成為iOS開發(fā)的標準工具(官方給出的數(shù)據(jù),超過42W個庫和300W個App使用了CocoaPods)。 本篇文章,非講述CocoaPods的教學文章拷呆,而是圍繞使用CocoaPods的兩個主題:依賴管理和Pod庫發(fā)布,講述些易忽略疫粥、混淆的關(guān)鍵點和不為熟知的用法。
點此查看原文:http://click.aliyun.com/m/41093/
作者:阿里-移動云-大前端
CocoaPods作為iOS的依賴管理工具腰懂,已然成為iOS開發(fā)的標準工具(官方給出的數(shù)據(jù)梗逮,超過42W個庫和300W個App使用了CocoaPods)。?
本篇文章绣溜,非講述CocoaPods的教學文章慷彤,而是圍繞使用CocoaPods的兩個主題:依賴管理和Pod庫發(fā)布,講述些易忽略怖喻、混淆的關(guān)鍵點和不為熟知的用法底哗。
執(zhí)行pod env,可查看本地環(huán)境:
CocoaPods: 1.2.0Ruby:ruby2.3.0p0(2015-12-25revision53290)[x86_64-darwin15]RubyGems: 2.5.1Host:MacOSX10.13.2(17C88)Xcode: 9.2(9C40b)Git:gitversion2.14.3(AppleGit-98)
1. 依賴管理
1.1 Podfile
Podfile是一個說明文件锚沸,描述一個或多個Xcode工程Target的依賴庫跋选,類似于Maven管理依賴的pom.xml文件。
Podfile可以很簡單哗蜈,也可以很復(fù)雜前标。
依賴版本號
依賴最新版本,不指定版本號:
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循未,無意義
實際使用時陷猫,可根據(jù)項目需求秫舌,靈活配置依賴版本號。
Hook
Podfile中可配置鉤子函數(shù)绣檬,在依賴庫安裝過程中會被調(diào)用足陨。主要有兩個Hook函數(shù):pre_install和post_install,接收的參數(shù)為:Pod::Installer娇未,分別對應(yīng)Pods工程安裝前和安裝后墨缘。
pre_install配置示例如下:
pre_installdo|installer|? puts'[Test] - pre_install here'end
post_install配置示例如下,Pods工程安裝后零抬,讀取打印iOS deploy target默認配置镊讼,并將其修改為8.0。
post_installdo|installer|? puts'[Test] - post_install here'installer.pods_project.targets.eachdo|target|? ? target.build_configurations.eachdo|config|? ? ? puts"[Test] - config:"+ config.name +", deploy target: "+ config.build_settings['IPHONEOS_DEPLOYMENT_TARGET']? ? ? config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] ='8.0'endendend
1.2 pod install vs. pod update
Podfile.lock
該文件用來記錄和追蹤生成的Pod版本平夜。?
pod install
每次執(zhí)行pod install蝶棋,都會重新下載并安裝pods。?
pods的版本號從Podfile.lock文件中獲群龆省:
有記錄的pods玩裙,直接下載安裝該記錄版本號的pods,不檢查對應(yīng)pods是否有更新段直;(已經(jīng)安裝的pods不會更新其版本)?
無記錄的pods吃溅,查找下載并安裝滿足Podfile中指定版本號條件的pods。?
pod update
完整命令為:pod update [PODNAME]鸯檬,執(zhí)行命令后决侈,CocoaPods會無視Podfile.lock鎖定的版本號,查找并更新到京闰,滿足Podfile中指定版本號條件的最新版本pods颜及;若沒有指定PODNAME,默認更新Podfile中全部pods蹂楣。?
pod outdated
滿足Podfile中指定版本號條件下俏站,列出比Podfile.lock中記錄鎖定的版本號新的pods。?
實際執(zhí)行pod update命令時痊土,更新的pods即為執(zhí)行pod outdated列出的pods肄扎。?
建議用法
工程首次執(zhí)行pod install或pod update,執(zhí)行效果一致赁酝。?
需要安裝新添加pod犯祠,建議執(zhí)行pod install或pod update [NEW_POD],已安裝的其他pods版本不變酌呆,否則可能由于版本更新的不確定性引起適配問題衡载。?
明確更新某pod版本時,執(zhí)行pod update [PODNAME]隙袁,明確更新全部pods版本時痰娱,執(zhí)行pod update弃榨。
1.3 pod cache
podcachelist[NAME]
可列出本地pods緩存記錄,執(zhí)行pod install或pod update時梨睁,若命中緩存記錄鲸睛,則直接從本地拉取。
podcacheclean[NAME]
刪除本地pods緩存記錄坡贺。?
執(zhí)行pod cache clean –all官辈,刪除全部緩存記錄。?
例:從私有CocoaPods倉庫拉取TestSDK v1.0.1遍坟,該記錄添加到本地緩存拳亿;由于某些原因TestSDK使用同樣的版本號v1.0.1做了覆蓋發(fā)布,可以先執(zhí)行pod cache clean TestSDK愿伴,然后再執(zhí)行pod update风瘦,保證拉取到最新版本的v1.0.1 SDK文件。
2. Pod庫發(fā)布
CocoaPods除了做依賴管理外公般,也會將自實現(xiàn)的pod庫上傳到公共倉庫/私有倉庫。
2.1 podspec
podspec文件胡桨,即Pod Specification(Pod描述文件)官帘,描述指定版本的pod庫信息,包括:pod庫源碼地址昧谊、文件列表刽虹、配置信息、描述信息等呢诬。
執(zhí)行pod spec create涌哲,可創(chuàng)建生成.podspec文件,其為Ruby語法格式尚镰,修改后如下阀圾,例:
Pod::Spec.newdo|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
執(zhí)行pod ipc spec xx.podspec,可將.podspec文件內(nèi)容從Ruby轉(zhuǎn)換為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倉庫本質(zhì)上是Git倉庫狗唉,倉庫里存儲的是各pod庫所有版本的.podspec或.podspec.json描述文件初烘。?
pod庫上傳,即對應(yīng)Git倉庫的commit提交分俯。
Pod庫上傳到公共倉庫肾筐,即向?公共Git倉庫?提交commit。
因此缸剪,CocoaPods私有倉庫的搭建吗铐,只需再準備一個Github/Gitlab倉庫;具體搭建流程不再描述杏节,可參考官網(wǎng)教程:CocoaPods - Private Pods唬渗。
執(zhí)行pod repo push REPO [NAME.podspec]上傳Pod庫到私有倉庫典阵,REPO為私有倉庫在本地的倉庫名。?
準備上傳的Pod庫谣妻,如果對其他pod庫有依賴萄喳,需要在.podspec文件中聲明dependency;同時執(zhí)行pod repo push命令時蹋半,添加--source參數(shù)他巨,聲明依賴要查找的倉庫地址;支持配置多個倉庫地址减江,以,分隔染突。
例:
# 準備上傳TestSDK到私有倉庫PrivateSpec,倉庫Git坐標:git@github.com/xx/xx-specs.git# TestSDK依賴ASDK和BSDK辈灼,其中ASDK位于公共master倉庫份企,BSDK位于私有倉庫# 上傳TestSDK時執(zhí)行命令如下:pod repopushPrivateSpec TestSDK.podspec--verbose --allow-warnings --source=git@github.com/xx/xx-specs.git,git@github.com:CocoaPods/Specs.git
2.3 依賴沖突
如果只從CocoaPods master倉庫拉取Pods,則不會有依賴沖突問題巡莹。依賴問題是由于引入三方私有CocoaPods倉庫導(dǎo)致的司志。?
首先來看pods依賴傳遞問題。
Pods依賴傳遞
假設(shè)TestSDK依賴ASDK和BSDK降宅,工程引入TestSDK后骂远,執(zhí)行pod install 或 pod update,會將TestSDK腰根、ASDK和BSDK一并拉取下來激才,這種可認為是依賴傳遞。
Pods依賴傳遞版本號管理
假設(shè)有依賴關(guān)系如下额嘿,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)
pod'TestSDK','1.0.2'pod'CSDK','1.0.1'
此時冰啃,需要顯式指定ASDK版本號,拉取下來SDK版本如下:
TestSDK(1.0.2)?
ASDK(1.0.1)?
BSDK(1.0.2)?
CSDK(1.0.1)
pod'TestSDK','1.0.2'pod'CSDK','1.0.1'pod'ASDK','1.0.1'
依賴沖突問題
存在于同時集成master公共倉庫和私有倉庫時刘莹,或集成多個私有倉庫時阎毅。
假設(shè)有兩個私有倉庫PrivateSpec1和PrivateSpec2,有SDK依賴關(guān)系如下点弯,其中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版本號半火。