红枫国度 2018-01-22 5129浏览量
作者:阿里-移动云-大前端
CocoaPods作为iOS的依赖管理工具,已然成为iOS开发的标准工具(官方给出的数据,超过42W个库和300W个App使用了CocoaPods)。
本篇文章,非讲述CocoaPods的教学文章,而是围绕使用CocoaPods的两个主题:依赖管理
和Pod库发布
,讲述些易忽略、混淆的关键点和不为熟知的用法。
执行pod env
,可查看本地环境:
CocoaPods : 1.2.0
Ruby : ruby 2.3.0p0 (2015-12-25 revision 53290) [x86_64-darwin15]
RubyGems : 2.5.1
Host : Mac OS X 10.13.2 (17C88)
Xcode : 9.2 (9C40b)
Git : git version 2.14.3 (Apple Git-98)
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。
~>
):'~> 1.0.1',版本号范围:1.0.1 <= version < 1.1
'~> 1.0',版本号范围:1.0 <= version < 2.0
'~> 0',版本号范围:0 <= version,无意义
实际使用时,可根据项目需求,灵活配置依赖版本号。
Podfile中可配置钩子函数,在依赖库安装过程中会被调用。主要有两个Hook函数:pre_install
和post_install
,接收的参数为:Pod::Installer,分别对应Pods工程安装前和安装后。
pre_install do |installer|
puts '[Test] - pre_install here'
end
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'
end
end
end
Podfile.lock
pod install
pod install
,都会重新下载并安装pods。pods的版本号从Podfile.lock
文件中获取:
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 install
或pod update [NEW_POD]
,已安装的其他pods版本不变,否则可能由于版本更新的不确定性引起适配问题。pod update [PODNAME]
,明确更新全部pods版本时,执行pod update
。pod cache list [NAME]
pod install
或pod update
时,若命中缓存记录,则直接从本地拉取。pod cache clean [NAME]
pod cache clean --all
,删除全部缓存记录。pod cache clean TestSDK
,然后再执行pod update
,保证拉取到最新版本的v1.0.1 SDK文件。CocoaPods除了做依赖管理外,也会将自实现的pod库上传到公共仓库/私有仓库。
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"
}
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.git
如果只从CocoaPods master仓库拉取Pods,则不会有依赖冲突问题。依赖问题是由于引入三方私有CocoaPods仓库导致的。
首先来看pods依赖传递问题。
假设TestSDK依赖ASDK和BSDK,工程引入TestSDK后,执行pod install
或 pod update
,会将TestSDK、ASDK和BSDK一并拉取下来,这种可认为是依赖传递
。
假设有依赖关系如下,TestSDK使用时,ASDK必须集成1.0.1版本,CSDK和ASDK(1.0.2)不能兼容。
TestSDK(1.0.2)
CSDK(1.0.1)
按下面的依赖配置,拉取下来的SDK版本如下,存在CSDK和ASDK不兼容问题。
pod 'TestSDK', '1.0.2'
pod 'CSDK', '1.0.1'
此时,需要显式指定ASDK版本号,拉取下来SDK版本如下:
pod 'TestSDK', '1.0.2'
pod 'CSDK', '1.0.1'
pod 'ASDK', '1.0.1'
存在于同时集成master公共仓库和私有仓库时,或集成多个私有仓库时。
假设有两个私有仓库PrivateSpec1和PrivateSpec2,有SDK依赖关系如下,其中ASDK1和ASDK2是同一SDK的不同Pod封装。
PrivateSpec1:
TestSDK1(1.0.0)
PrivateSpec2:
TestSDK2(1.0.1)
若同时依赖PrivateSpec1中的TestSDK1和PrivateSpec2中的TestSDK2,则ASDK1(1.0.0)和ASDK2(1.0.1)会冲突。
若Pods依赖支持类似Maven依赖的exclude
,将ASDK1或ASDK2其中之一exclude
,可解决该问题,但CocoaPods并不支持类似操作。
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
集结各类场景实战经验,助你开发运维畅行无忧