Cocoapods

Cocoapods 是iOS开发最常用的一个老牌包管理工具,类似npm,maven。

Cocoapods官网是这样介绍自己的

CocoaPods is a dependency manager for Swift and Objective-C Cocoa projects. It has over 83 thousand libraries and is used in over 3 million apps. CocoaPods can help you scale your projects elegantly.

它已经涵盖了8.3w个三方库,超过300w app在使用它。

下载

sudo gem install cocoapods
Cocoapods是ruby编写的,依赖于ruby环境,需要用到ruby的包管理工具rubygems

这里的下载命令用到sudo,是因为rubygems的默认安装目录/Library/Ruby/Gems/或者rvm默认安装目录~/.rvm/gems需要root权限,可参考rubygems安装目录

开始使用

首先我们创建一个新项目 TestCocoapods

Cocoapods提供了快捷命令pod init,用来创建Podfile文件

我们在Podfile文件中加上几个组件

platform :ios, '10.0'
target 'TestCocoapods' do
  pod 'AFNetworking'
  pod 'Masonry'
end

做完上面的准备工作,然后再执行一下 pod install 或者 pod update 命令就可以运行项目了.那么问题来了,pod install 或者 pod update 有啥区别呢?

pod install 和 pod update 到底有什么不同呢?

Answer:
官方文档pod install vs. pod update是这样说的:

Use pod install to install new pods in your project. Even if you already have a Podfile and ran pod install before; so even if you are just adding/removing pods to a project already using CocoaPods.
Use pod update [PODNAME] only when you want to update pods to a newer version.

官方建议只有在更新pod版本的时候才使用pod update,其他的情况都应该使用pod install

对pod install 的描述

Every time the pod install command is run — and downloads and install new pods — it writes the version it has installed, for each pods, in the Podfile.lock file. This file keeps track of the installed version of each pod and locks those versions.
When you run pod install, it only resolves dependencies for pods that are not already listed in the Podfile.lock.
For pods listed in the Podfile.lock, it downloads the explicit version listed in the Podfile.lock without trying to check if a newer version is available
For pods not listed in the Podfile.lock yet, it searches for the version that matches what is described in the Podfile (like in pod 'MyPod', '~>1.2')

pod install 会根据Podfile.lock文件所依赖的版本号进行下载,不会去检查是否有新版本存在,也不会更新仓库

对pod update 的描述

When you run pod update PODNAME, CocoaPods will try to find an updated version of the pod PODNAME, without taking into account the version listed in Podfile.lock. It will update the pod to the latest version possible (as long as it matches the version restrictions in your Podfile).

If you run pod update with no pod name, CocoaPods will update every pod listed in your Podfile to the latest version possible.
pod update 会忽略Podfile.lock文件,而去更新仓库的最新版本,符合Podfile所规定的版本,比如Podfile的依赖是这样的 ~> 1.2,如果仓库的最新版本是1.3版本,他就会更新到1.3,如果是2.x,则不会更新,版本依赖符号含义,可参考下方版本号控制

下面我们通过阅读Cocoapods的源码来了解一下这些不同,再看看还有那些不同是官网描述没有提到的。

分析

在看源码之前我们要先了解一下,Cocoapods不止是Cocoapods这一个仓库,而是拆分成了多个仓库,具体的项目可以查看Cocoapods-github的ReadMe-Projects ,还有一些官方的插件,可通过pod plugins installed命令查看。完整的依赖链可以查看Cocoapods-Master下的Gemfile文件。

我们今天阅读源码要涉及到的项目有下面几个,我们在下载Cocoapods的时候,这些项目也都被下载到gems目录下了

xcodeproj
解析整个Xcode工程,功能很强大,主要用来创建target,添加文件,添加Build Phases下的脚本等。

cocoapods-core
Cocoapods的实现库,包括spec和podfile。

CocoaPods-Downloader
下载库

claide
封装了命令行接口,自己写Ruby命令行工具也可以用这个库

Manifest.lock

Manifest.lock就是Podfile.lock的备份

  • 写入文件的方法会判断当前的lock文件和之前的lock文件是否相同,如果不相同则重写
  • install在podfile文件有增减pod的时候会触发重写
  • update在podfile文件有增减pod或者pod版本号变更的时候会重写
  • 所以如果podfile文件没有任何变更,不管是install还是update都不会重写Podfile.lock文件和Manifest.lock文件
  • Podfile.lock 和 Manifest.lock是同时写入的,Manifest.lock就是Podfile.lock的备份
  • Podfile.lock文件在项目根目录下 TestCocoapods/Podfile.lock
  • Manifest.lock文件在Pods目录下 TestCocoapods/Pods/Manifest.lock
  • 在build项目时,如果两个文件不一致,会报错 The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.
  • 这种错一般是你pull了别人的Podfile.lock文件,而别人的Podfile.lock文件变更了,导致和你本地的Manifest.lock不一致,这个时候就需要install或者update一下重写这两个文件
  • 比对脚本在Xcode的Build Phases下,每次install或者update的时候都会写入一个名为[CP] Check Pods Manifest.lock的Run Script Phase脚本
  • 写入方法在cocoapods/installer/user_project_integrator/target_integrator.rb/add_check_manifest_lock_script_phase中,如果想要用工具在Xcode中写入脚本,可以参考这个方法
总结

install的执行步骤:先解析podfile中的版本号,如果podfile中指定了版本号,则去本地仓库中找指定的版本号,如果没有找到对应版本号的内容,则报错。若podfile没有指定版本号,则会去podfile.lock中寻找版本号,如果是新增的库的话会去本地找该库最新的版本,如果找不到也报错。若podfile中可以找到版本号,则根据lock中的版本号去本地仓库找对应的版本号。若找不到也报错。上述步骤一旦能找到相应版本的库,则Copy到工程根目录的Pods文件下。

update的执行步骤:先git pull远端仓库,多个source的话要更新多个仓库,如果没有科学上网的话,要更新github上的官方仓库就得看命了。当然现在增加了CDN节点之后提高了分发和下载速度,不过还是不能解决因为不能科学上网而更新慢的问题。更新完仓库后,回去解析podfile中的版本号,如果指定了版本号,就去本地仓库中找指定的版本号,如果没找到,则报错。若podfile没有指定版本,则会直接去本地仓库找最新版本,若没找到,则报错。上述步骤一旦能找到相应版本的库,则Copy到工程根目录的Pods文件下。

所以若是不涉及版本更新的话,用install就够了!

备注
版本号控制

~> x.y.z 是指 >= x.y.z, <x.(y+1).z 的版本
~> x.y 是指 >= x.y, <(x+1).0 的版本
1. pod "AFNetworking"                       # 不指定依赖库版本,依赖最新版本
2. pod "AFNetworking", "2.0"                # 使用 = 2.0 的版本
3. pod "AFNetworking", "> 2.0"              # 使用 > 2.0 的版本
4. pod "AFNetworking", ">= 2.0"             # 使用 >= 2.0 的版本
5. pod "AFNetworking", "< 2.0"              # 使用 < 2.0 的版本
6. pod "AFNetworking", "<= 2.0"             # 使用 <= 2.0 的版本
7. pod "AFNetworking", '>= 2.0', '< 4.0     # 使用 >= 2.0,< 4.0 的版本
8. pod "AFNetworking", "~> 0.1.2"           # 使用 >= 0.1.2 , < 0.2 的版本
9. pod "AFNetworking", "~> 0.1"             # 使用 >= 0.1 , < 1.0 的版本
10. pod "AFNetworking", "~> 0"              # > 0 的版本,这个和1是一个效果

在组件化的项目工程中,一般是要写死组件版本号,否则会造成组内某些人版本号不一致而引发一系列问题。

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

推荐阅读更多精彩内容