中心化的包管理器:CocoaPods

在安装Linux软件时,我们是不是经常会遇到这样的问题:好不容下载了automake的源码包,结果./configure 时候提示先装autoconf,然后下载了个autoconf的源码,安装好后
发现automake的configure提示说autoconf的版本不对。

这一百个闹心的事,在后来的90后世界时很少出现了,因为现在的在Linux发行版引入了包管理系统来解决这个问题。目前有两大系列(当然还有其他系列),一个是Redhat主导的yum
命令的rmp软件包系列(Fedora/Redhat/CentOS),另一个是Debine引入的apt-xxx系列的deb包(Debine/Ubuntu)。这些包管理系统做的事情是主要为了解决软件安装过程的
依赖关系。比如安装A的1.9.1版本,需要先安装B的1.3.1以上版本,以及C的1.4.2以上版本。

同样的事情还会出现在我们引用第三方SDK库的时候,比如在Github上看到一个非常好用的X语言的Json库,然后下载到本地,集成到项目中。某天,发现这个Json库有个bug,同时发现
其在一个较新的版本中被修复了,那么这个时候,又要去Github上,吧代码down下来,然后再合入我们的项目中。如果项目结果组织的清晰(比如有目录名标示),替换过程还算好。否则
就是一百个痛快。在C/C++的世界里面,其实主要就是这么来引用的第三方库的:

1.若要使用第三方库,需要手动去找资源下载

2.若要更新库,就必须重新下载合入

在开源如火如荼、Github成为程序员Blog的今天,这样的问题更容易出现。因此现代化的语言要么通过工具来解决这样的问题。如Python的easy_install
,Java世界里面的Marven,Node.js(非新语言)的npm.要么在语言的层面便提供了支持,如Golang的 "go get"

在Mac的世界里面,CocoaPods就承担了此重任,其支持Objective-C以及Swift。

一、安装Cocoapods

Cocoapods是用Ruby写的,Mac下一般Ruby环境以及默认安装好了,如果没有则需要用brew或者手动安装下ruby的环境,这里不做介绍。打开终端,输入命令:

sudo gem install cocoapods

即可。由于ruby镜像被ZF的大墙挡住,因此可以选择配置国内的Ruby镜像,比如配置TaoBao的镜像(注意以前的http(http://ruby.taobao.org/非https已经停用了,现在都是https):

$ gem sources --remove https://rubygems.org/

$ gem sources -a https://ruby.taobao.org/

安装好了以后,我们可以运行:

pod --version 

来查看Cocoapods的版本,从而确认完成安装。至此就完成了对Cocoapods的安装了,是不是太简单?

二、安装第三方库

CocoaPods(下文中CocoaPods表示CocoaPods工具,而cocoapods表示示例的工程名)通过使用一个配置文件来管理工程中依赖的第三方库文件。在XCode工程的工程目录下,也就是xxx.xcodeproj 的同级目录创建一个Podfile文件。Cocoapods官方文档是用
touch命令生成 touch Podfile。这里我们以最常用到的AFNetworking库为例,创建一个Podfile文件,然后写上内容:

// 这里假设工程名叫做Cocoapods
target 'cocoapods' do
  pod 'AFNetworking', '~> 3.0'
  pod 'FBSDKCoreKit', '~> 4.9'
end

表示选择AFNetworking3.0的版本前最近的版本,而不是2.0老版本。此时目录结构如下:

// 这里假设工程名叫做cocoapods
Podfile         cocoapods.xcodeproj
cocoapods       cocoapodsTests

然后再Podfile同级目录下运行:

pod install 

// 提示:
czs-iMac:cocopods apollo$ pod install
Re-creating CocoaPods due to major version update.
Analyzing dependencies
Downloading dependencies
Installing AFNetworking (3.1.0)
Installing Bolts (1.7.0)
Installing FBSDKCoreKit (4.11.0)
Generating Pods project
Integrating client project
Sending stats
Pod installation complete! There are 2 dependencies from the Podfile and 3 total pods installed.

说明此时已经安装好AFNetworking 3.1.0以及FBSDKCoreKit4.11.0版本的库。

这个时候仔细看上面提示“There are 2 dependencies from the Podfile and 3 total pods”会发现我们虽然只指定了两个库,但是CocoaPods非常智能的帮我们推导出FBSDKCoreKit依赖Bolts并自动帮我们下载并安装上。这个就是CocoaPods这类包管理系统最强大的地方了。

此时我们再看目录结构为:

Podfile         Pods            cocoapods.xcodeproj  cocoapodsTests
Podfile.lock        cocoapods       cocoapods.xcworkspace

这里我们发现多了3个文件:

Podfile.lock
Pods
cocoapods.xcworkspace

Podfile.lock 记录了一些Meta信息,如cocoapods的版本、依赖库的版本等,可以认为是类似依赖信息的数据库文件。Pods目录里面存放了依赖库的库文件,如这里的AFnetworking/FBSDKCoreKit。
cocoapods.xcworkspace是一个类似XCode工程文件Cocoapods.xcodeproj文件的工程文件。

使用了cocoapods以后,就可以忽略cocoapods.xcodeproj了,并且不能用改文件打开工程,要使用cocoapods生成的这个xcworkspace。这里可以直接用XCode打开:

xcworkspace

此时,直接“Command+B”就可以直接编译工程。和一个普通的XCode工程是一样的。

看左边的工程目录结果,发现比普通的工程多了一个Pod工程依赖。原来的工程中多了一个“Pods”和“Frameworks”的Group。这两个Group主要就是配置文件和库的依赖。其他的Group
还是和一个普通的XCode工程一样的。在使用时,我们可以忽略这些新增的目录、工程已经Group。添加文件、设置工程就在原来的XCode工程上按一般的规则设置即可。

在Pods工程中,我们可以找到Pods的Group下有AFNetworking,所有第三方的framework都会在这个Group中。这里可以看到头文件和.m等其他文件,需要时可以过来进行查看。在工程中就可以直接引用AFNetworking库的API了。

三、Repo的Hint

在上面使用CocoaPods的过程中,使用pod工具生成了三个文件夹,那么在我们的Repo中,该如何对待这些文件呢?其实对于XCode工程,最好是在创建工程的那一刻就创建好.gitignore
文件,因为XCode会自己进行Add操作,当然这个是没有使用XCode的代码管理工具的情况下。在.gitigore中,我们把和Cocoapods相关的四个文件中仅“Podfile”放入git托管,二把其他三个生成的文件均写入.gitignore里面。这样多人之间仅共享配置文件,通过pod进行实时生成。

四、Podfile自定义

指定库的名称和版本

在上面的Podfile文件中,首先指定了一个Xcode工程的Targe然后写上需要依赖的库文件:

target 'cocoapods' do
  pod 'AFNetworking', '~> 3.0'
  pod 'FBSDKCoreKit', '~> 4.9'
end

Podfile是基于Ruby的,就如同Scons使用Python,Gradle使用Groovy一样,内容使用Ruby的语法。上面这个语句指定了依赖的库以及对应的版本。用pod关键字,加上单引号括上的库的名字和版本信息,中间用逗号分隔,版本信息规则如下:

版本号表示 版本
> 0.1 大于0.1的版本
>= 0.1 大于等于0.1 的版本
< 0.1 小于0.1的版本
<= 0.1 小于等于0.1 的版本
~> 0.1.2 0.1.2(含)到0.2(不含)之间的版本,也就是 >=0.1.2 && <0.2.0
~>0.1 同上 >= 0.1 && <1.0

除了用版本号表示CocoaPods收录的库外,还可以指定Github上的库:

pod 'AFNetworking', :git => 'https://github.com/gowalla/AFNetworking.git'
pod 'AFNetworking', :git => 'https://github.com/gowalla/AFNetworking.git', :branch => 'dev'
pod 'AFNetworking', :git => 'https://github.com/gowalla/AFNetworking.git', :tag => '0.7.0'
pod 'AFNetworking', :git => 'https://github.com/gowalla/AFNetworking.git', :commit => '082f8319af'

上面几条分别表示:

  • 使用trunck上的版本
  • 使用分支dev上的版本
  • 使用tag号版本
  • 使用commit号版本

自定义Target

Podfile通过Target
来组织依赖关系,Target就是我们普通XCode工程中的Target,每个Target产出一个Prouduct,因此只要设置好这个Target依赖的库文件,也就达到目的了。

target

每个Podfile有一个默认的Target,Cocoapods选择Podfile同级目录下的xcodeproj文件为默认工程,这也是上面为什么说要吧Podfile放在xcodeproj文件同级目录的原因。因此原来XCode工程文件中的第一个Target。所以上面的那一句话,其实是为我们的默认Target定义了一条依赖AFNetworking的规则。

注意,在1.0版本以前的CocoaPods支持不写Target的默认目标,在1.0之后就不可以了

target的定义符合Ruby的语法,用end结束:

target :'cocopods' do
  pod 'OCMock', '~> 2.0.1'
end

这样就定义了一个test的target依赖OCMock。

这里xcodeproj是根据默认规则的,也可以不将Profile文件放在其同级目录下,此时需要指定xcodeproj的位置:

xcodeproj './YourProj/cocopods.xcodeproj'

target :'cocopods' do
  pod 'OCMock', '~> 2.0.1'
end

对于每个依赖的库(比如这里的OCMock),还可以指定其编译时的sdk,如:

xcodeproj './YourProj/cocopods.xcodeproj'

target :'cocopods' do
    platform :ios, '7.0'   
    pod 'OCMock', '~> 2.0.1'
    
    platform :ios, '7.0'
    pod 'AFNetworking', '~> 0.2'
end

指定了OCMock和AFNetworking编译的使用用的SDK。

Bring it to all

了解了这几条规则,就够我们去定义自己工程中的依赖关系了。Podfile还提供了一些其他特性,比如“link_with”,"user_frameworkds"等,可以参考官方文档

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

推荐阅读更多精彩内容