近期在项目中首次使用了CocoaPods。从软件工程的角度来看,我对目前常见的CocoaPods使用方法有些意见,建议做一些改进。先说一下我建议的最佳实践,后面再分析为什么要这样做。并且希望大家根据自己公司的情况,讨论一下这几项建议是否合理,一起搞出一份真正的“最佳实践”。
 
CocoaPods的常见使用方法参见唐巧的文章《用CocoaPods做iOS程序的依赖管理》。在他的基础上,我提出几条补充。
 
1. CocoaPods生成的Pods目录*不*加入.gitignore,也就是说,第三方库的源码或binary要和产品代码一起,提交到公司内部的版本控制系统上。每次修改Podfile并执行pod update后,把Podfile、Podfile.lock、Pods目录下的改动一并签入。
2. 保证在任何时候只签出一次代码就能直接编译执行,不需要执行pod命令,甚至可以不装CocoaPods就能参与开发。
3. Podfile里所有的库使用精确版本号,不使用任何’~> 1.0', ‘>= 1.0'之类的版本号语法,只使用精确的版本号如'1.3.2'。
4. 在项目开发过程中,可以每隔一段时间使用pod outdated命令手动检查各第三方库是否有更新。如果发现某个库有新版本,去第三方库主页查看更新记录,并对版本变动做评估。如果确认有必要更新到最新版本,则修改Podfile里的版本号到最新版本,执行pod update。
5. 如果两个人同时修改了Podfile,第二个人git pull后发现有conflict,resolve顺序是:不动其他文件,先手动resolve Podfile的冲突;然后执行pod update;如果仍有冲突,可以用git reset把Podfile.lock和Pods目录恢复原状,再次执行pod update。此时应该没有pod相关的冲突了。
 
------------------------------------
 
以下分析常见CocoaPods用法的问题,首先看CocoaPods官网上的示例Podfile。
 
source 'https://github.com/CocoaPods/Specs.git'
pod 'AFNetworking', '~> 1.0'
 
这两行的含义是,使用github上的pods spec,安装AFNetworking 1.x系列最新的那个版本;如果AFNetworking还依赖于其他库,自动安装合适的版本。
 
假设现在我们的项目中要用到第三方库XYZ,开发流程大致如下:
1. 项目创建者张三在自己机器上安装好CocoaPods。
2. 张三执行pod init,在Podfile里添加代码 pod 'XYZ', '~> 1.0'。执行pod install,把Podfile和Podfile.lock签入代码管理,Pods目录添加到.gitignore。
3. 项目开发人员李四安装好CocoaPods。
4. 李四签出代码,编译,发现pod报错。于是执行pod install后,重新编译通过。
 
这样的CocoaPods使用方法可能引发很多异常情况。考虑第一类场景:
1. Github突然被盾了(曾经发生过)、或公司的外网出口挂了,李四无法成功执行pod install,因此只能眼巴巴的看着项目代码,无法编译。此时张三说,把我本地的Pods目录都拷给你一份吧,虽然这样拷来拷去容易出错,但暂时先这样临时解决吧。
2. Github突然被盾了,公司的持续集成服务器上无法执行pod install,也没法给服务器拷一份Pods目录。于是连续多天无法用持续集成。
3. XYZ开发者在修改代码时,从git上删除了最新版本的tag,并重新加tag到另一次commit上。于是张三和李四得到的XYZ代码是不同的。(虽然AFNetworking开发者很有经验,不太可能出这种错,但其他小的第三方库就不一定了。)
4. 五年后,早就没人使用古老的iOS 7了。XYZ开发者认为该库是针对iOS 7的,技术已经太陈旧,于是从Github上删除了该项目。(还好我们三年前就不再用这个库了。)但某一天公司有个新项目,想参考以前的代码。当打开代码执行pod install时,发现Github上已经没有XYZ库了。
 
以上情况可以归结为:你的代码是否可用严重依赖于别人。你从公司的版本控制系统上获取的代码不能直接编译,还依赖于世界各地很多其他人是否正确配置了他们的代码,还依赖于Github等git服务商是否可用,等等。在极端情况下,会有灾难性后果。
 
再看第二类场景:
5. 在我们项目的开发过程中,XYZ最新版本是1.4。一年后,我们重新打开旧的项目代码,执行pod install,获取到XYZ 1.x系列的最新版本1.7版。在XYZ 1.4到1.7版本之间,改变了一些接口和实现,我们的项目代码很有可能无法编译,或无法正确执行。
 
这里的问题是:常见的版本号写法'~> 1.0’会在pod install或pod update时检查版本更新,随时将第三方库升级到1.x系列的最新版本。对正在开发的项目来说,经常升级第三方库是可以的。但对已经发布的产品代码,这个变动是不可接受的。已发布的版本必须要有一份固定不变的代码,否则配置管理就失去了意义。
 
还有第三类场景:
6. 张三的CocoaPods安装的很早,和李四机器上的不是同一版本。这两个版本的CocoaPods对依赖规则的resolve算法不同,因此李四pod install失败,无法下载到和张三相同的第三方库代码。这是真事,两周前我们刚刚遇到了,后来解决方法是所有人都强制安装某个旧版本的CocoaPods。
 
这里的问题是:CocoaPods作为开发工具链中重要的一环,它的质量是否有保证?CocoaPods不是苹果官方的工具,也不是像git那样由极富经验的人组织设计开发,我们能否信任它的版本兼容性?具体来说,即不管用什么版本的CocoaPods,pod install后得到基本相同的第三方库。我们看到最近已经出了一个bug,如果时间再长点,三年后的CocoaPods会不会跟今天有较大差异?
对这个问题的一个解决方法是要求所有项目成员安装相同版本的CocoaPods,甚至安装相同版本的Ruby。但一个人需要同时参与多个项目的怎么办?问题的根源还是没变。
 
------------------------------------
 
基于以上分析,我提议的“最佳实践”解决了以下问题。
* Pods目录签入到版本控制系统,使产品代码没有外部依赖,不管什么时候都能从公司内网获取一份可直接运行的代码。
* 已发布版本的产品代码永久固定,不会随时间而变化,方便追踪问题和存档。
* 不要求项目成员装同样版本的CocoaPods,甚至可以不装CocoaPods。降低测试、设计人员使用代码的难度,也避免了CocoaPods本身兼容性引起的问题。
 
转自:http://www.weibo.com/p/1001603800875490492754

CocoaPods最佳实践探讨的更多相关文章

  1. 《开源安全运维平台OSSIM最佳实践》

    <开源安全运维平台OSSIM最佳实践> 经多年潜心研究开源技术,历时三年创作的<开源安全运维平台OSSIM最佳实践>一书即将出版.该书用80多万字记录了,作者10多年的IT行业 ...

  2. 基于AWS的云服务架构最佳实践

    ZZ from: http://blog.csdn.net/wireless_com/article/details/43305701 近年来,对于打造高度可扩展的应用程序,软件架构师们挖掘了若干相关 ...

  3. 【转】优化Web程序的最佳实践

    自动排版有点乱,看着蛋疼,建议下载中文PDF版阅读或阅读英文原文. Yahoo!的Exceptional Performance团队为改善Web性能带来最佳实践.他们为此进行了 一系列的实验.开发了各 ...

  4. fir.im Weekly - 2016 年 Android 最佳实践列表

    2016 年已经过去一半,你在年初制定的成长计划都实现了吗? 学海无涯,技术成长不是一簇而就的事情.本期 fir.im Weekly 推荐 王下邀月熊_Chevalier的 我的编程之路--知识管理与 ...

  5. .Net最佳实践3:使用性能计数器收集性能数据

    本文值得阅读吗? 本文讨论我们如何使用性能计数器从应用程序收集数据.我们将先了解的基本知识,然后我们将看到一个简单的示例,我们将从中收集一些性能数据. 介绍: - 我的应用程序的性能是最好的,像火箭 ...

  6. 腾讯优测优分享 | 探索react native首屏渲染最佳实践

    腾讯优测是专业的移动云测试平台,旗下的优分享不定时提供大量移动研发及测试相关的干货~ 此文主要与以下内容相关,希望对大家有帮助. react native给了我们使用javascript开发原生app ...

  7. 探索react native首屏渲染最佳实践

    文 / 腾讯 龚麒 0.前言 react native给了我们使用javascript开发原生app的能力,在使用react native完成兴趣部落安卓端发现tab改造后,我们开始对由react n ...

  8. MySQL性能优化的21个最佳实践

    http://www.searchdatabase.com.cn/showcontent_38045.htm MySQL性能优化的21个最佳实践 1. 为查询缓存优化你的查询 大多数的MySQL服务器 ...

  9. Rolling cURL: PHP并发最佳实践

    Rolling cURL: PHP并发最佳实践 在实际项目或者自己编写小工具(比如新闻聚合,商品价格监控,比价)的过程中, 通常需要从第3方网站或者API接口获取数据, 在需要处理1个URL队列时, ...

随机推荐

  1. 封装js千分位加逗号和删除逗号

    //封装js千分位加逗号和删除逗号 alert( format(2545678754.020001) ) //2,545,678,754.03 alert( format(-2545678754.02 ...

  2. sqoop的codegen工具

    一.codegen工具的使用 sqoop codegen --connect jdbc:mysql://localhost:3306/test --username root --password 1 ...

  3. yii在TbGridView的td里面加入相应的下拉选项(转)

    当你需要在一个GridView渲染某一个复杂元素的时候(特别是在这种情况下,这是一个小部件),这就需要你在控制器中调用一个动作.例如你给一个GridView的定义这样的一列: <?php $th ...

  4. nandflash操作详解

    1.nandflash就是嵌入式系统的硬盘 2.分类(1)MLC:存储单元格存储两位,慢,偏移,寿命短,容量大(2)SLC:存储一位.快,寿命长,容量小,昂贵 3访问:(1)独立编址,有专用的控制器, ...

  5. 第一节:CLR寄宿

    本系列文章来自 CLR VIA C# .NET FrameWork在Microsoft  Windows平台的顶部运行.这意味着.NET必须用Windows可以理解的技术来构建.首先,所有的托管模块和 ...

  6. 统计工具之QQ图

    正态 QQ 图和普通 QQ 图 分位数-分位数 (QQ) 图是两种分布的分位数相对彼此进行绘制的图.评估数据集是否正态分布,并分别研究两个数据集是否具有相似的分布. 如何构建正态 QQ 图 首先,数据 ...

  7. unix的策略与机制

    策略同机制分离,接口同引擎分离 Linux/Unix设计理念提供的一种机制不是策略.如果说机制是一种框架,那么,策略就是填充框架的一个个具体实施.机制提供的就是一种开放而宽松的环境,而策略就是在这个环 ...

  8. [Environment Build] Win10下Appach配置

    1. Apache下载,登录http://httpd.apache.org/download.cgi,选择Files for Microsoft Windows, 有以下几个选择, 我选择的是Apac ...

  9. hdu 5281 Senior's Gun

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5281 Senior's Gun Description Xuejiejie is a beautifu ...

  10. [译]rabbitmq 2.5 Where’s my message? Durability and you

    我对rabbitmq学习还不深入,这些翻译仅仅做资料保存,希望不要误导大家. There’s a dirty secret about creating queues and exchanges in ...