首页 关于 微信公众号
欢迎关注我的微信公众号

关于 Podfile.lock 带来的痛

发生了什么

你加入一个 iOS 项目,根据小伙伴给你的 git 仓库地址把代码 clone 下来,在项目目录下 ls -al 看一下:

$ ls -al
.
..
.DS_Store
.git
.gitignore
Podfile
TestProject
TestProject.xcodeproj
TestProject.xcworkspace

项目用了 CocoaPods 来管理依赖库,于是你找到 Podfile 所在的目录,执行 pod install 命令安装依赖库,一切都很正常。

直到你安装完依赖库后,用 git status 命令看了一下本地 git 仓库的状态,发现提示:

$ git status
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

	modified:   Podfile.lock

no changes added to commit (use "git add" and/or "git commit -a")

你开始疑惑:我就安装了一下依赖库,啥都没干呢,Podfile.lock 是什么鬼?算了,不管了,先 Run 一下项目再说,嗯,没啥嘛,一切正常,项目成功跑起来了。上网搜了下 Podfile.lock,原来是用来锁定项目依赖库版本的文件。赶紧 git commitgit push 把 Podfile.lock 加入 git 管理,并提交到公共库。

写了两天代码,小伙伴告诉你项目代码更新了需要同步一下,于是你 git commitgit pull,还好,合并正常。

这时候你准备 Build 一下项目,却发现 Xcode 在报错:

PhaseScriptExecution Check Pods Manifest.lock...
...
error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.

又是 Podfile.lock 这鬼?等等,还有 Manifest.lock 又是啥?

Podfile.lock 是啥

Podfile.lock 是在第一次运行 pod install 时生成的,Podfile.lock 中会标注项目当前依赖库的准确版本,其中包括了项目在 Podfile 中直接标注使用的库,以及这些库依赖的其他库。这样的好处是当你跟小伙伴协同开发时,你的小伙伴同步了你的 Podfile.lock 文件后,他执行 pod install 会安装 Podfile.lock 指定版本的依赖库,这样就可以防止大家的依赖库不一致而造成问题。因此,CocoaPods 官方强烈推荐把 Podfile.lock 纳入版本控制之下。

但是,Podfile.lock 并不是一成不变的,当你修改了 Podfile 文件里使用的依赖库或者运行 pod update 命令时,就会生成新的 Podfile.lock 文件。

所以,协同开发时需要注意使用 pod installpod update 的区别:

// Podfile
pod 'iRate'

// Podfile.lock
PODS:
  - iRate (1.11.1)

DEPENDENCIES:
  - iRate

SPEC CHECKSUMS:
  iRate: 178e61bf5610493c363e2819056cf1a186b9ebd9

COCOAPODS: 0.35.0

Manifest.lock 又是啥

Manifest.lock 是 Podfile.lock 的副本,每次只要生成 Podfile.lock 时就会生成一个一样的 Manifest.lock 存储在 Pods 文件夹下。在每次项目 Build 的时候,会跑一下脚本检查一下 Podfile.lock 和 Manifest.lock 是否一致:

image

如果不一致,你就会看到第一节说到的报错了:

PhaseScriptExecution Check Pods Manifest.lock...
...
error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.

这样做的原因是 Pods 目录并不总是被放到版本控制之下,有了这个检查机制就能保证开发团队的各个小伙伴能在运行项目前更新他们的依赖库,并保持这些依赖库的版本一致,从而防止在依赖库的版本不统一造成程序在一些不明显的地方编译失败或运行崩溃。

到底发生了什么

说清楚了 Podfile.lock 和 Manifest.lock 到底是什么,现在我们回头再看看第一节到底发生了什么。现在你可以看第一节里的各种类似下面的信息了:

这些记录是小伙伴 A、代码服务器 Server 和自己本地 Me 这三个地方的 Podfile.lock、Manifest.lock 在不同场景下的版本状态。

第一个问题:

第二个问题:

除了上面这些问题,另外再提醒一下:注意 pod installpod update 的区别。如果不合理的使用 pod update 也可能会给你带来一些困惑。

怎么对待 Podfile.lock

讲完上面这些,那么究竟该怎样对待 Podfile.lock 呢?以下建议可供参考:

Blog

Opinion

Project