【iOS开发工程化——开发中】使用CocoaPods管理三方库

目录
一、三方库的版本管理
  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 installpod update命令】,目的依然是减少一些兼容性问题或依赖冲突。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,219评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,363评论 1 293
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,933评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,020评论 0 206
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,400评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,640评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,896评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,597评论 0 199
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,327评论 1 244
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,581评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,072评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,399评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,054评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,083评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,849评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,672评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,585评论 2 270

推荐阅读更多精彩内容