目录
一、三方库的版本管理
1、Podfile文件
2、Podfile.lock文件
3、Pods文件夹
4、Workspace文档
二、三方库的版本更新
一、三方库的版本管理
创建一个名字叫做TestApp的项目,创建好本地仓库,添加好.gitignore文件和README.md文件。
cd到TestApp,执行pod init
命令来创建Podfile文件。
打开Podfile文件,添加三方库AFNetwoking。
cd到TestApp,执行pod install
命令来安装三方库AFNetworking,安装完成后,CocoaPods会自动帮我们生成一个Podfile.lock文件、一个Pods文件夹和一个TestApp.xcworkspace文档。
接下来我们就一一介绍这四个东西,不过在介绍之前,我们先简单捋一下CocoaPods到底是沿着哪条线路完成依赖库的安装的,看不懂没关系,先有个印象即可。
- 第一步:cd到项目,执行
pod install
命令 - 第二步:首先CocoaPods会找到项目的Podfile文件,根据
pod 'AFNetworking', '= 2.0.0'
这样的语句知道项目依赖了哪些依赖库,比如这里CocoaPods就知道项目依赖了三方库AFNetworking - 第三步:然后CocoaPods就会拿着AFNetworking,去Podfile.lock文件里查找它到底使用了哪个版本,根据的语句是
- AFNetworking (= 2.0.0)
,比如这里CocoaPods就知道了AFNetworking使用的版本是2.0.0 - 第四步:然后CocoaPods就会拿着AFNetworking和它的版本2.0.0去Podfile文件里
source 'https://cdn.cocoapods.org/'
指向的podspec文件仓库里找到AFNetworking、2.0.0版本的podspec文件 - 第五步:然后CocoaPods就能根据AFNetworking、2.0.0版本的podspec文件里的主页
"homepage": "https://github.com/AFNetworking/AFNetworking"
和git地址"git": "https://github.com/AFNetworking/AFNetworking.git"
来安装AFNetworking了
Podfile文件
Podfile文件的作用:主要用来描述项目里各个target的依赖库。
其实通过pod init
命令创建的Podfile文件只是个简版的,实际开发中我们会使用一个较为完整版的Podfile文件如下,我们会逐行解释每一行是什么意思。
source 'https://cdn.cocoapods.org/'
source 'YourCompanySpecs的git地址'
platform :ios, '9.0'
use_frameworks!
# ignore all warnings from all dependencies
inhibit_all_warnings!
def thirdPods
pod 'AFNetworking', '= 2.0.0'
end
def privatePods
# Git依赖
pod 'BaseLib_UI', '= 1.0.0'
# 本地依赖
pod 'BaseLib_Network', :path => '/Users/yiyi/Desktop/BaseLib_Network'
end
target 'TestApp' do
thirdPods
privatePods
end
- source
source用来指向podspec文件仓库,以便CocoaPods能根据source找到相应的podspec文件仓库,进而在podspec文件仓库里找到某个依赖库、某个版本的podspec文件。
具体地说,当我们使用三方库时,source需要指向CocoaPods官方的podspec文件仓库,这个仓库由CocoaPods官方维护,它里面存放着所有三方库、所有版本的podspec文件,这个仓库的名字叫做Specs,git地址为https://github.com/CocoaPods/Specs.git
。但是因为CocoaPods经常被开发者吐槽依赖库下载很慢,所以CocoaPods使用了CDN(Content Delivery Network,内容分发网络)来缓存整个CocoaPods官方的podspec文件仓库, 方便开发者快速下载,有了CDN我们就不需要再使用镜像了,CocoaPods1.8之后默认使用CDN。所以三方库的source要像下面这么写:
source 'https://cdn.cocoapods.org/'
当我们使用私有库时,source需要指向你们公司自己的podspec文件仓库,这个仓库由你们公司自己维护,它里面存放着所有私有库、所有版本的podspec文件,我们可以参考CocoaPods给这个仓库取名叫做YourCompanySpecs,git地址就是该仓库的远程仓库地址。如果我们的项目里使用了私有库,那么私有库的source要像下面这么写:
source 'YourCompanySpecs的git地址'
- platform和use_frameworks!
platform :ios, '9.0'
use_frameworks!
platform用于指定该项目支持的操作系统及支持的最低版本,注意必须和General那里设置的最低版本一致。
use_frameworks!这一配置会让CocoaPods把所有的依赖库都打包生成一个动态库供我们的项目使用,动态库能有效地加快编译和链接的速度,减小包体积。而如果我们把use_frameworks!注释掉,那么CocoaPods就会把所有的依赖库都打包生成一个静态库供我们的项目使用。需要注意的是Swift只支持以动态库的方式来加载三方库。
- inhibit_all_warnings!
# ignore all warnings from all dependencies
inhibit_all_warnings!
正如注释所言,这一配置可以去掉CocoaPods引入的依赖库的警告。
- 组织相同类型的依赖库
def thirdPods
pod 'AFNetworking', '= 2.0.0'
end
def privatePods
# Git依赖
pod 'BaseLib_UI', '= 1.0.0'
# 本地依赖
pod 'BaseLib_Network', :path => '/Users/yiyi/Desktop/BaseLib_Network'
end
我们可以通过def 小写字母开头的标识符 ... end
代码块把相同类型的依赖库组织在一起,这样方便管理。
- target
target 'TestApp' do
thirdPods
privatePods
end
我们可以把构建目标target所使用的所有依赖库都放进target '...' do ... end
代码块里,执行pod install
的时候,CocoaPods会自动把thirdPods和privatePods展开为AFNetworking和BaseLib_UI、BaseLib_Network。
介绍了Podfile文件,我们就可以来谈谈依赖库的版本管理了。在CocoaPods里,每一个依赖库都称为一个pod,在Podfile文件里我们可以通过pod 'AFNetworking', '= 2.0.0'
这样的格式来配置要使用的依赖库及其版本,其中AFNetworking是依赖库的名字,2.0.0为其版本。
我们建议【统一使用=
来锁死依赖库的版本 + 把Podfile文件加入版本控制】,这样一来就算我们没把Podfile.lock文件加入版本控制,也可以保证单人或多人开发时,每次执行执行pod install
命令时都能安装到同一版本的依赖库,因为大家的Podfile是共享的,又都是=
,所以CocoaPods就总是会生成一模一样的Podfile.lock文件,这就相当于是把Podfile.lock文件加入版本控制了,而不至于这个库发布了新版本、CocoaPods自动给你安装了最新版本、而带来一些兼容性问题或依赖冲突。当然除了=
操作符以外,CocoaPods还提供了其他操作符来指定版本:
> 0.1
:表示大于0.1的任何版本,如0.1.1、0.2、1.0等>= 0.1
:表示大于或等于0.1的任何版本< 0.1
:表示小于0.1的任何版本<= 0.1
:表示小于或等于0.1的任何版本~> 0.1.2
:表示大于0.1.2且最高支持0.1.x的版本,如0.1.3、0.1.9等,不能超过0.2
Podfile.lock文件
Podfile.lock文件的作用:主要用来记录某一次pod install
所有依赖库的实际版本,由CocoaPods自动生成和更新。
比如我们在Podfile文件这么写:pod 'AFNetworking', '>= 2.0.0'
,那么AFNetworking实际安装的版本为:4.0.1(目前的最新版),在Podfile.lock文件里的记录如下:
PODS:
- AFNetworking (4.0.1):
- AFNetworking/NSURLSession (= 4.0.1)
- AFNetworking/Reachability (= 4.0.1)
- AFNetworking/Security (= 4.0.1)
- AFNetworking/Serialization (= 4.0.1)
- AFNetworking/UIKit (= 4.0.1)
- AFNetworking/NSURLSession (4.0.1):
- AFNetworking/Reachability
- AFNetworking/Security
- AFNetworking/Serialization
- AFNetworking/Reachability (4.0.1)
- AFNetworking/Security (4.0.1)
- AFNetworking/Serialization (4.0.1)
- AFNetworking/UIKit (4.0.1):
- AFNetworking/NSURLSession
比如我们在Podfile文件这么写:pod 'AFNetworking', '< 2.0.0'
,那么AFNetworking实际安装的版本为:1.3.4(小于2.0.0的最新版),在Podfile.lock文件里的记录如下:
PODS:
- AFNetworking (1.3.4)
比如我们在Podfile文件这么写:pod 'AFNetworking', '~> 2.0.0'
,那么AFNetworking实际安装的版本为:2.0.3(2.0.x的最新版),在Podfile.lock文件里的记录如下:
PODS:
- AFNetworking (2.0.3):
- AFNetworking/NSURLConnection (= 2.0.3)
- AFNetworking/NSURLSession (= 2.0.3)
- AFNetworking/Reachability (= 2.0.3)
- AFNetworking/Security (= 2.0.3)
- AFNetworking/Serialization (= 2.0.3)
- AFNetworking/UIKit (= 2.0.3)
- AFNetworking/NSURLConnection (2.0.3):
- AFNetworking/Reachability
- AFNetworking/Security
- AFNetworking/Serialization
- AFNetworking/NSURLSession (2.0.3):
- AFNetworking/NSURLConnection
- AFNetworking/Reachability (2.0.3)
- AFNetworking/Security (2.0.3)
- AFNetworking/Serialization (2.0.3)
- AFNetworking/UIKit (2.0.3):
- AFNetworking/NSURLConnection
比如我们在Podfile文件这么写:pod 'AFNetworking', '= 2.0.0'
,那么AFNetworking实际安装的版本为:2.0.0(锁死了版本),在Podfile.lock文件里的记录如下:
PODS:
- AFNetworking (2.0.0):
- AFNetworking/NSURLConnection (= 2.0.0)
- AFNetworking/NSURLSession (= 2.0.0)
- AFNetworking/Reachability (= 2.0.0)
- AFNetworking/Security (= 2.0.0)
- AFNetworking/Serialization (= 2.0.0)
- AFNetworking/UIKit (= 2.0.0)
- AFNetworking/NSURLConnection (2.0.0):
- AFNetworking/Reachability
- AFNetworking/Security
- AFNetworking/Serialization
- AFNetworking/NSURLSession (2.0.0):
- AFNetworking/Reachability
- AFNetworking/Security
- AFNetworking/Serialization
- AFNetworking/Reachability (2.0.0)
- AFNetworking/Security (2.0.0)
- AFNetworking/Serialization (2.0.0)
- AFNetworking/UIKit (2.0.0):
- AFNetworking/NSURLConnection
由上述四个例子可以看出我们不能完全相信Podfile文件里依赖库的版本,因为并不是所有公司的版本管理方案都是在Podfile文件里锁死依赖库的版本,他们可能会使用>、>=、<、<=、~>
来进行依赖库的版本管理,这样一来我们就根本无法从Podfile文件里得知项目到底使用了哪个版本的依赖库。而Podfile.lock文件就可以,每当我们执行了pod install
命令后,CocoaPods就会根据Podfile文件里使用的依赖库版本管理标识符解释出各个依赖库到底应该安装哪个版本,然后安装并一一记录在Podfile.lock文件里。所以如果让你去确定你们的App到底使用了哪个版本的依赖库,你应该去找Podfile.lock文件,而不是Podfile文件,Podfile文件更像是提供了一个依赖库的版本约束,而并非具体的版本。
我们建议【把Podfile文件加入版本控制 + 把Podfile.lock文件加入版本控制】,这样一来就算我们在Podfile文件里不采用锁死版本的方案,也可以保证单人或多人开发时,每次执行执行pod install
命令时都能安装到同一版本的依赖库,因为CocoaPods安装哪个版本的库最终都是依据Podfile.lock文件里的记录来的,而不至于这个库发布了新版本、CocoaPods自动给你安装了最新版本、而带来一些兼容性问题或依赖冲突。
当然,我们最终建议依赖库的版本管理方案为:【统一使用
=
来锁死依赖库的版本 + 把Podfile文件加入版本控制 + 把Podfile.lock文件加入版本控制】,目的就是单人或多人开发时,每次执行执行pod install
命令时都能安装到同一版本的依赖库,而不至于带来一些兼容性问题或依赖冲突。
Pods文件夹
Pods文件夹的作用:这个文件夹里存放着一个Pod项目和所有依赖库的源码文件,Pods项目用来统一管理所有的依赖库,当我们在Podfile里指定构建成动态库时,该项目会自动生成一个Pods_项目名称.framework
的动态库供我们的项目使用,而当我们在Podfile里指定构建成静态库时,该项目会自动生成一个libPods-项目名称.a
的静态库供我们的项目使用。
Workspace文档
Workspace文档的作用:Workspace是Xcode管理子项目的方式,通过Workspace我们可以把相关联的多个Xcode子项目组合起来方便开发,在TestApp中,Workspace文档就统一管理了我们的主项目TestApp.xcodeproj和Pods项目Pods.xcodeproj。与此同时,CocoaPods还会修改我们主项目的Build Phases把Pods_项目名称.framework
动态库或libPods-项目名称.a
静态库嵌入到我们的主项目中,以上所有操作都是由CocoaPods自动帮我们完成的。后续的开发,我们都得打开Workspace文档而不是原有的Xcode项目文档来进行。
二、三方依赖库的版本更新
上面我们已经建议依赖库的版本管理方案为:【统一使用=
来锁死依赖库的版本 + 把Podfile文件加入版本控制 + 把Podfile.lock文件加入版本控制】。
这里建议依赖库的版本更新方案为:【继续统一使用=
来锁死依赖库要升级到的版本 + 执行pod install
或pod update
命令】,目的依然是减少一些兼容性问题或依赖冲突。