玩转CocoaPods

作者: 猫耳呀 | 来源:发表于2018-01-29 14:55 被阅读0次

    摘要: >> 作者:阿里-移动云-大前端 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: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可以很简单,也可以很复杂。

    依赖版本号

    依赖最新版本,不指定版本号:

    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_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

    每次执行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

    podcachelist[NAME]

    可列出本地pods缓存记录,执行pod install或pod update时,若命中缓存记录,则直接从本地拉取。

    podcacheclean[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.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

    执行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 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仓库导致的。 

    首先来看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)

    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公共仓库和私有仓库时,或集成多个私有仓库时。

    假设有两个私有仓库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

        本文链接:https://www.haomeiwen.com/subject/oqvxzxtx.html