背景:
在日常开发中,我们的项目中都会使用到三方库,并且会选择使用 CocoaPods 进行管理。这其中我们就会经常遇到关于 podfile.lock 要不要提交,podfile.lock 的作用是干嘛的以及冲突怎么解决,pod install 和 pod update 有什么区别等这些问题
,下面就来详细介绍下如何解决这些问题。
什么是 CocoaPods
CocoaPods
是OS X和iOS下的一个第三类库管理工具,通过CocoaPods工具我们可以为项目添加被称为Pods
的依赖库(这些类库必须是CocoaPods本身所支持的),并且可以轻松管理其版本。
CocoaPods的好处
1、在引入第三方库时它可以自动为我们完成各种各样的配置,包括配置编译阶段、连接器选项、甚至是ARC环境下的-fno-objc-arc配置等。
2、使用CocoaPods可以很方便地查找新的第三方库,这些类库是比较“标准的”,而不是网上随便找到的,这样可以让我们找到真正好用的类库。
关于CocoaPods可以参考这篇文章:www.jianshu.com/p/9e4e36ba8…
这篇文章主要用来介绍CocoaPods的原理和使用注意事项。
CocoaPods 集成原理
CocoaPods 的原理是将所有的依赖库都放到另一个名为Pods的项目中,然而让主项目依赖Pods项目, 这样,源码管理工作任务从主项目移到了Pods项目中。
1.Pods项目最终会编译成一个名为libPods.a的文件, 主项目只要依赖这个.a文件即可.
2.对于资源文件, CocoaPods提供了一个名为Pods-resources.sh的bash脚本, 该脚本在每次项目
编译的时候都会执行,将第三方库的各种资源文件复制到目标目录中.
3.CocoaPods通过一个名为Pods.xcconfig的文件在编译设置所有的依赖和参数
libPods.a
Pods-resources.sh
Pods.xcconfig
Cocoapods的下载原理
s.source = { :git => 'git@10.210.0.140:app/iOS-XXX.git', :tag => '1.0.0' }
-
根据:git => ‘git@10.210.0.140:app/iOS-XXX.git’找到对应的git仓库;
-
根据:tag => ‘1.0.0’定位到对应
tag的提交
(如果没有注明Pod依赖库版本则定位到最后一次的提交); -
在这次提交中检索后缀为.podspec的文件(文件可以随便命名),验证s.name是否与Podfile中的一致;
-
如果不一致则install时会报错:
[!]Unable to find a specification for ‘React’
。验证成功后,就会根据Podspec中的s.source_files找到需要导入的代码文件,并通过其他的的数据找到对应的配置文件或资源文件等; -
然后将其下载到本地项目中。
注意:
如果是共有库,这些原理也相同。只是共有库要将podspec文件上传到cocoapods。在导入的时候通过名字React去cocoapods匹配对应的podspec,然后根据s.source去找到对应的仓库和对应的版本,然后会再去匹配新的podspec,后边的步骤就完全相同了。
版本控制原理
当执行完 pod install之后,cocoapods 会生成一个podfile.lock
的文件。podfile.lock 文件最大的用处在于多人开发。如果你没有在podfile中指定pods版本pod ‘React’,那么默认为获取当前React依赖库的最新版本
。
当团队中的某个人执行完 pod install 命令后,生成的 podfile.lock 文件就记录下了当时最新 pods 依赖库的版本
,这时团队中的其他人 check 下来这份包含 podfile.lock 文件的工程以后,再去执行 pod install 命令时,获取下来的 pods 依赖库的版本和最开始用户获取到的版本一致
。如果没有podfile.lock文件,后续所有用户执行pod install命令都会获取最新版本的React,这就可能造成一个团队使用的依赖库版本不一致,这对团队协作来说绝对是个灾难。在这种情况下,如果团队想使用当前最新版本的React依赖库,有两种方案
:
1、更改podfile,使其指向最新版本的‘React’依赖库
2、执行pod update命令;鉴于podfile.lock文件对团队协作如此重要,所以应该加入到版本控制里面。
podfile.lock到底要不要提交
podfile.lock文件是需要提交的。
当我们app组件化之后,一个app会包含各种不同的版本组件,而主工程变成一个壳子,用Podfile文件依赖了各种不同的组件, 然后我们的app完成了一次版本迭代上线之后,这个时候需要主工程相对应的组件版本,相对应版本的组件又依赖其他版本组件,如果我们手动通过spec管理肯定非常麻烦,又如果我们直接把全部的组件都写在podfile中,那我们每次的时候回溯
(我们现在在开发2.0版本,想回到1.0版本)的时候,都需要首先记录之前app版本中对应的全部组件的版本,然后再在podfile中写上对应的组件版本号,如果组件特别多,需要回溯多次,这样也是非常痛苦的。那有没有最简单一句命令一个执行操作一分钟一步到位回溯之前
的版本的方法呢?这个时候我们就需要依靠podfile.lock文件进行版本管理。
Podfile.lock 中会标注项目当前依赖库的准确版本
,其中包括了项目在 Podfile 中直接标注使用的库,以及这些库依赖的其他库。这样的好处是当你跟小伙伴协同开发时,你的小伙伴同步了你的 Podfile.lock 文件后,他执行 pod install 会安装 Podfile.lock 指定版本的依赖库,这样就可以防止大家的依赖库不一致而造成问题。因此,CocoaPods 官方强烈推荐把 Podfile.lock 纳入版本控制之下。
所以如果我们用 Podfile.lock 文件进行版本管理,只需要在主工程(就是那个壳子)中把Podfile.lock 纳入版本控制之下(也就是把主工程对应的 Podfile.lock文件上传到gitlab
),并且主工程中的 Podfile文件一定不要指定版本号, 然后把app 每次封版本的时候在gitlab打上相应的版本号tag,每次我们想回溯之前版本 只需要切换到当时的tag,然后执行 pod install (千万不能执行 pod upodate,因为执行完 pod upodate 对应的 Podfile.lock 里面的库版本会跟着更新
)就可以了就是这么简单。
podfile.lock冲突的解决
diff: /../Podfile.lock: No such file or directory
diff: Manifest.lock: No such file or directory
error: The sandbox is not **in** sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.`
平常开发过程中,项目在执行完 pod install 后提示 Podfile.lock 文件被修改,需要提交。但是其他同事(同事电脑的pod版本和你的不一致)拉下来代码后,运行项目发现了这个错误,然后执行 pod install ,解决了这个问题,然后再提交了 Podfile.lock 文件。等你再更新代码发现也出现了这个问题,这就会陷入一个死循环。而我们又不能不提交 Podfile.lock 文件,所以这个问题的解决版本就是将大家电脑的pod版本号保持一致
。
删除旧版本号
sudo gem uninstall -n /usr/local/bin cocoapods -v XXX
安装新版本号的pod
sudo gem install -n /usr/local/bin cocoapods -v XXX
Pod install 和 Pod update的区别
pod install:用于第一次为项目下载pods,还有后续增加或者删除库的时候。
pod update: 用于更新库的版本。会遍历所有的库进行更新,并更新 Podfile.lock 文件。
pod update name: 只会更新指定的库。
pod repo update: 更新整个.cocoapods下的所有库的配置文件,挨个检查对应的框架有没有新版本发布,有的话更新本地的资源配置文件.
pod install --no-repo-update:根据podfile文件或者podfile.lock下载并导入对应的第三方库,跳过检查资源配置文件是否需要更新的环节
使用示例
示例1:项目需要依赖A、B、C
三个库,当前三个库的版本都是1.0.0,创建 Podfile 文件,执行Pod install
。会拉取这三个库,并且Podfile.lock
中 A、B、C 的版本都会锁定为1.0.0。
示例2:项目需要增加一个 pod D,在 Podfile 文件中引入D,这里应该使用 pod install。因为只是想增加D,而不想更新其他三个库。
示例3:这时假如团队其他成员加入这个项目,克隆了项目仓库,然后执行 'pod install'。由于Podfile.lock被提交了,所以能确保新成员使用的库版本和我的是一样的。即使 pod A 有'1.1.0' 版本可以使用,因为 Podfile.lock中锁定的Pod A的版本是1.0.0。
示例4:检查版本更新,如果想更新 pod A到1.1.0版本,而 pod B也有新版本但是不想更新 pod B,这个时候就使用 pod update A 就可以了,这个时候 Podfile.lock 中 pod A的版本信息也会更新。
注意:使用固定版本的 Podfile,例如 pod 'A', '~> 1.1.0',这样是不是可以确保项目中的所有成员使用的都是同一个版本?答案是否定的,当在执行 pod update时,只能保证'A'的版本是固定的,但是如果'A'还依赖 pod A1,甲同学拉取的时候A1版本为1.0.0,而当乙同学拉取时 pod A1 最新版本是 '1.1.0' 版本了,就会导致A1的版本为 '1.1.0' 了。这就是为什么确保团队每个成员使用在不同电脑使用同一版本的唯一方式时使用 Podfile.lock 并且适当使用 pod install 和 pod update 。
版本号的逻辑关系
'> 0.1' --- 版本号大于0.1的
‘>= 0.1’ --- 版本0.1和版本号大于0.1的
'< 0.1' --- 版本号小于0.1的
‘<= 0.1' --- 版本号0.1和版本号小于0.1的
版本号的最优匹配
‘~> 0.1.2' --- 版本0.1.2和版本号处于0.1.2-0.2之间的,不包括0.2和更高版本
‘~> 0.1' --- 版本0.1和版本号处于0.1-1.0之间的,不包括1.0和更高版本
‘~> 0' --- 版本0和更高,和没设没啥区别
总结
本文介绍了git提交是podfile.lock
要不要提交,podfile.lock 的作用是干嘛的以及冲突怎么解决。pod install 和 pod update 有什么区别。
参考文章: