CocoaPods——深刻理解 CocoaPods

本文由 伯乐在线 - programmer.du 翻译自 Michele Titolo。欢迎加入技术翻译小组。转载请参见文章末尾处的要求。

html

  Cocoapods是 OS X 和 iOS 下的一个第三方库管理工具。你能使用CocoaPods添加被称做“Pods”的依赖库,并轻松管理它们的版本,而不用考虑当前的时间和开发环境。git

  Cocoapods意义体如今两个方面。首先,引入第三方库无可避免地要进行各类各样的配置。对于Objective-C的初级开发者来讲,项目配置但是一件艰巨的任务。在配置编译阶段和连接器选项的过程当中,极有可能引入许多人为的错误。而CocoaPods简化了这一切,它能自动配置编译选项,拯救了开发者。xcode

  其次,使用CocoaPods能够很方便地查找新的第三方库。固然,这可不是说让你七拼八凑别人代码而开发出一个“移栽”应用。而是让你找到真正好用的库,缩短你的开发周期,提高你的代码质量。缓存

  接下来,咱们将经过分析pod安装的过程,一步步揭示CocoaPods背后的技术。ruby

核心组件

  CocoaPods是用ruby写的,并划分红了若干个Gem包。CocoaPods在解析执行过程当中最重要的几个包的路径分别是:CocoaPods/CocoaPods、 CocoaPods/Core 和 CocoaPods/Xcodeproj。markdown

  CocoaPods / CocoaPodapp

  这是面向用户的组件,每当你执行一个pod命令时,这个组件将被激活。它包括了全部实用CocoaPods的功能,而且还能调用其余gem包来执行任务。ide

   CocoaPods / Core工具

  Core gem提供了与CocoaPods相关的文件(主要是Podfile和podspecs)的处理。post

  Podfile

  Podfile用于配置项目所须要的第三方库。它能被高度定制,因此你能够尽量地给它添加你想要的特性。若是您还想对Podfile了解更多的话,请查看Podfile指南(地址 http://guides.cocoapods.org/syntax/podfile.html)。

  Podspec

  .podspec文件描述了一个库将怎样被添加进工程中。.podspec文件能够标识该第三方库所须要的源码文件、依赖库、编译选项,以及其余第三方库须要的配置。

  CocoaPods / Xcodeproj

  这个包负责工程文件直接关系的处理。它能建立以及修改.xcodeproj文件和.xcworkspace文件。它也能够做为一个独立的包使用,当你要编写修改项目文件的脚本时,能够考虑使用CocoaPods/Xcodeproj。

运行 pod install 命令

  pod install的执行引起了不少操做。了解底层运行过程最简单的方式就是给pod install语句添加 –verbose 参数。如今,运行

pod install --verbose

  将会出现如下执行结果:

Analyzing dependencies 

Updating spec repositories
Updating spec repo `master` 
$ /usr/bin/git pull
Already up-to-date.

Finding Podfile changes
- AFNetworking
- HockeySDK

Resolving dependencies of `Podfile`
Resolving dependencies for target `Pods' (iOS 6.0)
- AFNetworking (= 1.2.1)
- SDWebImage (= 3.2)
- SDWebImage/Core

Comparing resolved specification to the sandbox manifest
- AFNetworking
- HockeySDK

Downloading dependencies

-> Using AFNetworking (1.2.1)

-> Using HockeySDK (3.0.0)
- Running pre install hooks
- HockeySDK

Generating Pods project
- Creating Pods project
- Adding source files to Pods project
- Adding frameworks to Pods project
- Adding libraries to Pods project
- Adding resources to Pods project
- Linking headers
- Installing libraries
- Installing target `Pods-AFNetworking` iOS 6.0
- Adding Build files
- Adding resource bundles to Pods project
- Generating public xcconfig file at `Pods/Pods-AFNetworking.xcconfig`
- Generating private xcconfig file at `Pods/Pods-AFNetworking-Private.xcconfig`
- Generating prefix header at `Pods/Pods-AFNetworking-prefix.pch`
- Generating dummy source file at `Pods/Pods-AFNetworking-dummy.m`
- Installing target `Pods-HockeySDK` iOS 6.0
- Adding Build files
- Adding resource bundles to Pods project
- Generating public xcconfig file at `Pods/Pods-HockeySDK.xcconfig`
- Generating private xcconfig file at `Pods/Pods-HockeySDK-Private.xcconfig`

 - Generating prefix header at `Pods/Pods-HockeySDK-prefix.pch`

- Generating dummy source file at `Pods/Pods-HockeySDK-dummy.m`
- Installing target `Pods` iOS 6.0
- Generating xcconfig file at `Pods/Pods.xcconfig`
- Generating target environment header at `Pods/Pods-environment.h`
- Generating copy resources script at `Pods/Pods-resources.sh`
- Generating acknowledgements at `Pods/Pods-acknowledgements.plist`
- Generating acknowledgements at `Pods/Pods-acknowledgements.markdown`
- Generating dummy source file at `Pods/Pods-dummy.m`
- Running post install hooks
- Writing Xcode project file to `Pods/Pods.xcodeproj`
- Writing Lockfile in `Podfile.lock`
- Writing Manifest in `Pods/Manifest.lock`
Integrating client project

  整个过程当中执行了不少操做,不过把它们分解以后,会发现它们都很简单。让咱们逐步来分析。

  阅读Podfile文件

  你是否吐槽过Podfile的语法太过诡异,其实这是ruby的语法而不是OC。相较而言,Podfile要比现有的其余格式更加简单好用一些。

  安装的第一步是要弄清楚哪些第三方库被显式或隐式地声明了。CocoaPods加载podspecs文件时,获取了第三方库的名称及版本列表。Podsspecs文件存储在本地,路径为~/.cocoapods。

  版本控制和冲突

  CocoaPods使用语义版本命名约定来解决对版本的依赖。因为冲突解决系统创建在非重大更改的补丁版本之间,这使得解决依赖关系要容易得多。举个栗子,两个彻底不一样的第三方库同时依赖CocoaLumberjack。它们其中一个依赖的版本是2.3.1,而另外一个则为2.3.3,解析器能够自动使用较新的版本,在这里则是2.3.3,由于这能够与2.3.1向后兼容。

  但这并不老是有效。有许多第三方库还并不支持这个约定,这让解决方案变得很是复杂。

  固然,老是会有一些冲突须要手工解决。若是一个第三方库依赖CocoaLumberjack 1.2.5,而另外一个依赖CocoaLumberjack 2.3.1,最后只能靠调用这两个第三方库的用户来手动地决定CocoaLumberjack的版本了。

  加载源码

  CocoaPods执行的下一个步骤是加载源代码。每一个.podspec文件都包含了源代码的索引,这些索引通常指向了一个git地址或者git tag。它们以commit SHA码的方式存储在 ~/Library/Caches/CocoaPods中。而在这些路径中建立文件则由 Core 包负责。

  源代码将依照Podfile、.podspec和缓存文件的信息下载到相应的第三方库路径。

  生成Pods.xcodeproj

  每次pod install 执行后而且检测到改动时,Pods.xcodeproj文件将呗Xcodeproj gem更新。若是Pods.xcodeproj文件不存在,则会以默认配置生成,若已存在,则Pods.xcodeproj会使用现有的配置。

  安装第三方库

  当Cocoapods向项目中增长了一个第三方库的时候,不只仅是将添加代码这么简单。因为每一个第三方库有不一样的target,因此每次添加第三方库时,都只有几个文件被添加。每一个源代码都须要:

  • 一个包含编译选项的.xcconfig文件
  • 一个同时拥有编译设置和CocoaPods默认配置的私有.xcconfig文件
  • 编译所必须的prefix.pch文件
  • 另外一个编译必须的文件dummy.m

  一旦每一个pod的target都完成了以上步骤,整个Pods的Target就会被建立。这增长了相同的文件,与另外几个。若是有源代码中包含了资源bundle,向app的target中添加bundle的方式将写入Pods-Resources.sh。还有一个叫Pods-environment.h的文件,文件中含有许多检查组件是否来自pod的宏定义。最后,将生成两个确认文件,一个.plist文件,一个用于给用户查阅许可信息的markdown文件。

  写入到磁盘

  直到如今,许多已完成的过程都使用的是内存中的对象。为了让这些过程的结果可重复被使用,咱们须要将全部结果都记录在一个文件中。因此Pods.xcodeproj和另外两个很是重要的文件:Podfile.lock和Manifest.lock都将被写入磁盘。

  Podfile.lock

  这是CocoaPods建立的最重要的文件之一。它记录了须要被安装的pod的每一个已安装的版本。若是你想知道已安装的pod是哪一个版本,能够查看这个文件。推荐将Podfile.lock文件加入到版本控制中,这有助于整个团队的一致性。

  Manifest.lock

  这是每次运行pod install时建立的Podfile.lock文件的副本。若是你见过“沙盒文件和Podfile.lock文件不一样步”的错误,这个错误就是因Manifest.lock文件和Podfile.lock文件不同引发。因为Pods所在的目录并不总在版本控制之下,这样能够保证开发者运行app以前都能更新他们的pods,不然app可能会crash,或者在一些不太明显的地方编译失败

  xcproj

  若是您已经依照咱们的建议在系统上安装了xcproj,它会将您的Pods.xcodeproj文件转换成就旧有ASCII格式的plist文件。为何要这么作呢?由于Xcode所依赖和使用的plist在好久之前就已经不被其余软件支持了。若是没有xcproj,你的Pods.xcodeproj文件将会以XML格式的plist文件存储,当你用Xcode打开它时,它会被改写,形成大量的文件冲突。

运行结果

  运行pod install的最终结果是许多文件被添加到你的工程和系统中。这个过程一般只须要几秒钟。固然没有Cocoapods这些事也均可以完成。只不过所花的时间就不只仅是几秒而已了。

旁注:持续集成

  CocoaPods和持续集成在一块儿很是融洽。虽然持续集成很大程度上取决于你的项目配置,但Cocoapods依然能很容易地对项目进行编译。

  Pods文件夹已加入版本控制的持续集成

  若是包括Pods文件夹的一切东西都在版本控制之中,那么你不须要特别作什么就可以持续集成。因为编译时必须指定一个scheme,因此只须要保证使用了正确的scheme便可。

  没有Pods文件夹的持续集成

  若是你的Pods文件夹没有被归入版本控制之中,那么你须要一些额外的步骤来保证持续集成的顺利进行。最起码,Podfile文件要放入版本控制之中。另外强烈建议将生成的.xcworkspace文件和Podfile.lock文件归入版本控制,这样不只简单方便,更能保证所使用的Pod是正确的版本。

  一旦配置完毕,让CocoaPods在CI上正确运行的关键是保证每次编译以前都执行了pod install。在大多数系统中,譬如Jenkins或者Travis,你只用把“pod install”定义为一个编译步骤便可(实际上,Travis会自动执行pod install)。随着Xcode Bot的发布,咱们尚未找到能像书写的这么流畅的解决方案,不过咱们正朝着解决方案努力,一旦成功,咱们将会当即分享。

结束语

  CocoaPods简化了OC的开发流程,咱们的目标是让第三方库更容易被发现和添加。了解CocoaPods的原理能让你作出更好的App。咱们沿着CocoaPods的整个流程一步步执行,从载入specs文件和源代码、建立.xcodeproj文件和全部组件到将全部文件写入磁盘。因此接下来,咱们运行 pod install –verbose,静静观察CocoaPods的魔力如何显现。

相关文章
相关标签/搜索