[TOC]
# 1. 介绍
许多以 CocoaPods 开始的人似乎认为 `pod install` 仅在您第一次使用 CocoaPods 设置项目时使用,并且之后使用 `pod update`。 但事实并非如此。
本指南的目的是解释何时应使用 `pod install` 以及何时应使用 `pod update`。
* 使用 `pod install` 在您的项目中安装新的 pods。 即使您之前已经有了 Podfile 并运行了 `pod install`, 所以即使你只是添加/删除 pods 到已经使用 CocoaPods 的项目。
* 仅当您想将 Pod 更新为新版本时才使用 `pod update [PODNAME]`。
# 2. 命令的详细介绍
> 注意:安装与更新的词汇并不是特定于 CocoaPods 的。 它受到了许多其他依赖管理器的启发,如 [Bundler](http://bundler.io/),[RubyGems](https://rubygems.org/) 或 [composer](https://getcomposer.org/),它们都有类似的命令,其行为和意图与本文档中描述的完全相同。
## 2.1 pod install
这是在您第一次检索项目的 pod 时使用的,也是每次编辑 Podfile 以添加,更新或删除 pod 的时候使用的。
* 每次运行 `pod install` 命令并下载并安装新的 pod 时,都会在 Podfile.lock 文件中为每个 pod 写入已安装的版本。 该文件会跟踪每个 pod 的安装版本并锁定这些版本。
* 运行 `pod install` 时,它仅解决 Podfile.lock 中未列出的 pod 的依赖关系。
* 对于 Podfile.lock 中列出的 Pod,它会下载 Podfile.lock 中列出的显式版本,而不尝试检查是否有更新的版本可用
* 对于没有在 Podfile.lock 中列出的 pod,它会搜索与 Podfile 中描述的内容相匹配的版本(例如在“Pod”中,如 `'Pod','〜> 1.2'`)
## 2.2 pod outdated
当您运行 `pod outdated` 时,CocoaPods 将列出所有具有比 Podfile.lock 中列出的更新版本的 pod(当前为每个 pod 安装的版本)。 这意味着如果您在这些 pod 上运行 `pod update PODNAME`,则只要新版本与您的 Podfile 中设置的`pod'MyPod','〜> x.y'` 等限制匹配,它们就会更新。
## 2.3 pod update
当您运行 `pod update PODNAME` 时,CocoaPods 将尝试查找 pod PODNAME 的更新版本,而不考虑 Podfile.lock 中列出的版本。 它会将 pod 更新为最新版本(只要它符合 Podfile 中的版本限制)。
如果您运行没有 pod 名称的 `pod update`,CocoaPods 会将 Podfile 中列出的每个 pod 更新为最新版本。
# 3. 预期用法
使用 `pod update PODNAME`,您将只能更新特定的 Pod(检查是否存在新版本并相应地更新 Pod)。 与之相反, `pod install` 不会尝试更新已安装的 pod 版本。
当您向 Podfile 添加 Pod 时,应该运行 `pod install` ,而不是 `pod update` - 安装此新 Pod,而不必担心在同一进程中更新现有Pod。
当您想要更新特定 Pod(或所有Pod)的版本时,您只能使用 `pod update` 。
# 4. 提交你的 Podfile.lock
提醒一下,即使您的策略不是将 Pods 文件夹提交到共享存储库,也应该始终提交并推送您的 Podfile.lock 文件。
否则,它会打破上面解释的关于 pod 安装能够锁定已安装版本的 pod 的整个逻辑。
# 5. 场景示例
以下是一个场景示例,用于说明在项目生命周期中可能遇到的各种用例。
## 5.1 阶段1:用户1创建项目
user1 创建一个项目并希望使用 pod A,B,C。 他们使用这些窗格创建 Podfile,然后运行 `pod install`。
这将安装 pod A,B,C,它们都在 1.0.0 版本中。
Podfile.lock 会记录下来,注意 A,B和C 每个都安装为版本 1.0.0 。
> 顺便说一下,因为这是他们第一次运行 `pod install`,并且 Pods.xcodeproj 项目尚不存在,该命令还会创建 Pods.xcodeproj 和 .xcworkspace,但这是该命令的副作用,而不是其主要功能。
## 5.2 阶段2:用户1添加一个新的窗格
稍后,user1 想要将 Pod D 添加到其 Podfile 中。
因此,他们应该在之后运行 `pod install`,以便即使 pod B 的开发人员在第一次执行`pod install` 后发布了 pod 的 1.1.0 版本,该项目仍会继续使用 1.0.0 版本 - 因为user1 只需要添加 Pod D,而不会冒着对 Pod B 的意外更新的风险。
> 有些人认为它错了,因为他们在这里使用 `pod update` - 可能认为这是“我想用新的 pod 更新我的项目”? - 而不是使用 `pod install` - 在项目中安装新的 pod 。
## 5.3 阶段3:用户2加入该项目
然后,从未参与过该项目的用户2加入该团队。 他们克隆仓库,然后使用 pod 安装。
Podfile.lock(应该提交到git仓库)的内容将确保它们将获得完全相同的 pod,并且使用与user1完全相同的版本。
即使版本 1.2.0 的版本 C 现在可用,user2 也将获得版本 1.0.0 中的版本 C. 因为这是在 Podfile.lock 中注册的内容。 pod C 被 Podfile.lock 锁定为版本 1.0.0(因此是该文件的名称)。
## 5.4 阶段4:检查一个Pod的新版本
稍后,user1 需要检查是否有任何更新可用于 pods 。 他们运行 `pod outdated`,这将告诉他们 pod B 有一个新的 1.1.0 版本,而 pod C 有一个新的 1.2.0 版本发布。
user1决定他们想更新 pod B,但不是 pod C ; 所以他们将运行` pod update B`,它将B 从版本 1.0.0 更新到版本 1.1.0(并且相应地更新 Podfile.lock),但会保留版本 1.0.0 中的 pod C(并且不会将其更新为 1.2.0)。
# 6. 在 Podfile 中使用精确的版本是不够的
有些人可能会认为,通过在其 Podfile 中指定其 Pod的精确版本,例如pod'A','1.0.0',足以保证每个用户都拥有与团队中其他人相同的版本。
然后,他们甚至可以使用 ` pod update `,即使只是添加一个新Pod,也认为从来不会冒更新其他 Pod 的风险,因为它们固定到 Podfile 中的特定版本。
但事实上,这还不足以保证我们上述场景中的 user1 和 user2 将始终获得完全相同版本的所有 Pod 。
一个典型的例子是,如果 pod A 依赖于 pod A2 - 在 A.podspec 中声明为依赖关系 `'A2','〜> 3.0'` 。 在这种情况下,在 Podfile 中使用 pod'A' , '1.0.0' 确实会强制user1 和 user2 都使用 pod A 的版本 1.0.0,但是:
* user1 最终可能会在版本 3.4 中得到 A2 (因为那时是A2的最新版本)
* 而当 user2 稍后加入项目时运行 `pod install` 时,他们可能会在版本 3.5 中获得 pod A2(因为 A2 的维护者可能同时发布了新版本)。
这就是为什么确保每个团队成员使用每台计算机上所有pod的相同版本的唯一方法是使用 Podfile.lock 并正确使用 `pod install` 与 ` pod update `。