pod install 与 pod update

<简介

许多 CocoaPods 初学者似乎认为 pod install 仅在首次使用 CocoaPods 设置项目时使用,而 pod update 则在之后使用。但事实并非如此。

本指南的目的是解释何时应使用 pod install,何时应使用 pod update


TL;DR

  • 使用 pod install 在项目中安装新 pod即使您已有 Podfile 并之前运行过 pod install;因此,即使您只是向已使用 CocoaPods 的项目添加/移除 pod。
  • 仅当您要将 pod 更新到较新版本时,才使用 pod update [PODNAME]

<命令的详细介绍

注意:installupdate 的术语实际上并非 CocoaPods 特有。它受到许多其他依赖项管理器(如 bundlerRubyGemscomposer)的启发,这些管理器具有类似的命令,其行为和意图与本文档中描述的命令完全相同。

<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 'MyPod', '~>1.2' 中所示)

<pod outdated

当您运行 pod outdated 时,CocoaPods 会列出所有较新版本高于 Podfile.lock 中列出的版本(每个 pod 当前安装的版本)的 pod。这意味着如果您对这些 pod 运行 pod update PODNAME,它们将被更新——只要新版本仍与您在 Podfile 中设置的限制(如 pod 'MyPod', '~>x.y')相匹配。

<pod update

当你运行 pod update PODNAME 时,CocoaPods 将尝试查找 pod PODNAME 的更新版本,而不会考虑 Podfile.lock 中列出的版本。它将 pod 更新到可能的最新版本(只要它与 Podfile 中的版本限制相匹配)。

如果你在没有 pod 名称的情况下运行 pod update,CocoaPods 将把 Podfile 中列出的每个 pod 更新到可能的最新版本。

<预期用途

使用 pod update PODNAME,你将只能更新一个特定的 pod(检查是否存在新版本并相应地更新 pod)。与 pod install 相反,后者不会尝试更新已安装的 pod 的版本。

当你向 Podfile 添加一个 pod 时,你应该运行 pod install,而不是 pod update — 以安装这个新 pod,而不会冒在同一过程中更新现有 pod 的风险。

你将只在想要更新特定 pod(或所有 pod)的版本时使用 pod update

<提交你的 Podfile.lock

提醒一下,即使你的策略是不将 Pods 文件夹提交到共享仓库你应该始终提交和推送你的 Podfile.lock 文件

否则,它将破坏上面解释的关于 pod install 能够锁定 pod 已安装版本的整个逻辑。

<场景示例

这里有一个场景示例来说明项目生命周期中可能遇到的各种用例。

<阶段 1:用户 1 创建项目

用户 1 创建了一个项目,并希望使用 pod ABC。他们使用这些 pod 创建了一个 Podfile,并运行 pod install

这将安装 pod ABC,我们假设它们都处于版本 1.0.0 中。

Podfile.lock 将跟踪该内容,并注意 ABC 均安装为版本 1.0.0

顺便提一下,因为这是他们第一次运行 pod install,并且 Pods.xcodeproj 项目尚不存在,因此该命令还将创建 Pods.xcodeproj.xcworkspace,但这只是该命令的副作用,而不是其主要作用。

<阶段 2:User1 添加一个新 Pod

稍后,user1 希望向其 Podfile 中添加一个 Pod D

因此,他们应该随后运行 pod install,这样,即使 Pod B 的维护者在首次执行 pod install 之后发布了其 Pod 的版本 1.1.0,该项目仍将继续使用版本 1.0.0 — 因为 user1 只想添加 Pod D,而不想冒 Pod B 意外更新的风险。

有些人在这里做错了,因为他们使用了 pod update — 可能认为这是“我想使用新的 Pod 更新我的项目”? — 而不是使用 pod install — 在项目中安装新的 Pod。

<阶段 3:User2 加入该项目

然后,从未在该项目上工作过的 user2 加入团队。他们克隆存储库,然后使用 pod install

Podfile.lock(应该提交到 git 存储库)的内容将保证他们获得完全相同的 Pod,以及 user1 使用的完全相同的版本。

即使 Pod C 的版本 1.2.0 现在可用,user2 也将获得版本 1.0.0 的 Pod C。因为这是在 Podfile.lock 中注册的内容。Pod C 已被 Podfile.lock 锁定到版本 1.0.0(因此该文件得名)。

<阶段 4:检查 Pod 的新版本

稍后,user1 希望检查是否有任何更新可用于 Pod。他们运行 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会将 Pod C 保留在版本 1.0.0 中(并且不会将其更新到 1.2.0)。

<Podfile 中使用确切版本还不够

有些人可能认为,在 Podfile 中指定其 Pod 的确切版本(例如 pod 'A', '1.0.0')就足以保证每个用户都与团队中的其他人拥有相同的版本。

然后,他们甚至可能使用 pod update,即使只是添加一个新 pod 时,认为它永远不会冒着更新其他 pod 的风险,因为它们被固定在 Podfile 中的特定版本。

但事实上,这不足以保证在上述场景中 user1user2 始终获得所有 pod 的完全相同版本

一个典型的例子是,如果 pod A 依赖于 pod A2 — 在 A.podspec 中声明为 dependency 'A2', '~> 3.0'。在这种情况下,在 Podfile 中使用 pod 'A', '1.0.0' 确实会强制 user1user2 都始终使用 pod A 的版本 1.0.0,但是

  • user1 最终可能会使用版本 3.4 的 pod A2(因为那是当时 A2 的最新版本)
  • 而当 user2 在稍后加入项目时运行 pod install 时,他们可能会获得版本 3.5 的 pod A2(因为 A2 的维护者可能在此期间发布了新版本)。

这就是确保每个团队成员在每台计算机上使用所有 pod 的相同版本,唯一的方法是使用 Podfile.lock 并正确使用 pod installpod update