面试

关于 Podfile.lock 带来的痛

2018-06-04  本文已影响0人  bo_song

原文地址:http://www.samirchen.com/about-podfile-lock/

发生了什么

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

1.  `$ ls -al`
2.  `.`
3.  `..`
4.  `.DS_Store`
5.  `.git`
6.  `.gitignore`
7.  `Podfile`
8.  `TestProject`
9.  `TestProject.xcodeproj`
10.  `TestProject.xcworkspace`

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

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


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

5.  `modified:  Podfile.lock`

7.  `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 在报错:

1.  `PhaseScriptExecution  Check  Pods  Manifest.lock...`
2.  `...`
3.  `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 文件主要包含三个块:PODSDEPENDENCIESSPEC CHECKSUMS,用来记录每个pod的版本号、依赖的其他库和每个库对应的podspec.json文件的 checksum(SHA-1算法)。通过这些信息可以确保多人协作的时候,大家使用的是相同版本的第三方库。

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 的区别:

> 
> 1.  `// Podfile`
> 2.  `pod 'iRate'`
> 
> 4.  `// Podfile.lock`
> 5.  `PODS:`
> 6.  `- iRate (1.11.1)`
> 
> 8.  `DEPENDENCIES:`
> 9.  `- iRate`
> 
> 11.  `SPEC CHECKSUMS:`
> 12.  `iRate:  178e61bf5610493c363e2819056cf1a186b9ebd9`
> 
> 14.  `COCOAPODS:  0.35.0`
> 

Manifest.lock 又是啥

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

[图片上传中...(image-161986-1528042688816-0)]

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

1.  `PhaseScriptExecution  Check  Pods  Manifest.lock...`
2.  `...`
3.  `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 冲突问题

之前公司项目中使用了FBRetainCycleDetector这个第三方库来检查内存泄露,在升级到某一个版本后,出现部分同事的 podfile.lock中FBRetainCycleDetector的checksum 值不一致,每次都需要运行 pod install 来更新 podfile.lock,然后git push 到仓库。其他的同事又出现 podfile.lock 冲突,需要运行 pod install 更新,然后push到 git 仓库。

喜剧上演多次后,我们采取少数服从多数的原则,让出现冲突的同事git push 的时候手动去掉 podfile.lock。

项目中遇到的是 podfile.lockchecksum 部分的冲突,其实就是由于FBRetainCycleDetector.podspec.json文件的checksum不一致。

通过对比了有冲突的同事 mac 中生产的FBRetainCycleDetector.podspec.json文件,发现主要是repuires_arc 字段中的文件列表顺序不同。

在找到问题产生的原因后,就着手解决问题:

一开始怀疑是MAC的 locale 不同导致文件的排序不一致,因为之前使用翻译脚本来做文件排序的时候,也出现过类似的问题。

但是在设置了 locale环境变量之后,问题还是没有解决。

前两天,在FBRetainCycleDetector的 issues 列表中,发现也有人遇到了相同的问题,更加可喜的是,这个小伙子提了一个 PR 修复了这个问题,其实只有一行代码:

image.png

问题是如何解决的:

在运行pod install后,生成FBRetainCycleDetector.podspec.json文件中, repuires_arc字段是需要设置-fno-objc-arc的文件列表,但是不知道某种原因,出现文件路径排序在不同电脑上不同,从而导致最后FBRetainCycleDetector.podspec.jsonCHECKSUMS(SHA-1)值不一致。

使用 sort 方法后,解决了文件排序问题

怎么对待 Podfile.lock

那么究竟该怎样对待 Podfile.lock 呢?以下建议可供参考:

参考:

上一篇 下一篇

猜你喜欢

热点阅读