http://objccn.io/issue-6-4/html
CocoaPods 是开发 OS X 和 iOS 应用程序的一个第三方库的依赖管理工具。利用 CocoaPods,能够定义本身的依赖关系 (称做 pods
),而且随着时间的变化,以及在整个开发环境中对第三方库的版本管理很是方便。git
CocoaPods 背后的理念主要体如今两个方面。首先,在工程中引入第三方代码会涉及到许多内容。针对 Objective-C 初级开发者来讲,工程文件的配置会让人很沮丧。在配置 build phases 和 linker flags 过程当中,会引发许多人为因素的错误。CocoaPods 简化了这一切,它可以自动配置编译选项。github
其次,经过 CocoaPods,能够很方便的查找到新的第三方库。固然,这并非说你能够简单的将别人提供的库拿来拼凑成一个应用程序。它的真正做用是让你可以找到真正好用的库,以此来缩短咱们的开发周期和提高软件的质量。swift
本文中,咱们将经过分析 pod 安装 (
pod install)
的过程,一步一步揭示 CocoaPods 背后的技术。xcode
CocoaPods是用 Ruby 写的,并由若干个 Ruby 包 (gems) 构成的。在解析整合过程当中,最重要的几个 gems 分别是: CocoaPods/CocoaPods, CocoaPods/Core, 和 CocoaPods/Xcodeproj (是的,CocoaPods 是一个依赖管理工具 -- 利用依赖管理进行构建的!)。缓存
编者注 CocoaPods 是一个 objc 的依赖管理工具,而其自己是利用 ruby 的依赖管理 gem 进行构建的ruby
这是是一个面向用户的组件,每当执行一个 pod
命令时,这个组件都将被激活。该组件包括了全部使用 CocoaPods 涉及到的功能,而且还能经过调用全部其它的 gems 来执行任务。markdown
Core 组件提供支持与 CocoaPods 相关文件的处理,文件主要是 Podfile 和 podspecs。app
Podfile 是一个文件,用于定义项目所须要使用的第三方库。该文件支持高度定制,你能够根据我的喜爱对其作出定制。更多相关信息,请查阅 Podfile 指南。ide
.podspec
也是一个文件,该文件描述了一个库是怎样被添加到工程中的。它支持的功能有:列出源文件、framework、编译选项和某个库所须要的依赖等。
这个 gem 组件负责全部工程文件的整合。它可以对建立并修改 .xcodeproj
和 .xcworkspace
文件。它也能够做为单独的一个 gem 包使用。若是你想要写一个脚原本方便的修改工程文件,那么可使用这个 gem。
pod install
命令当运行 pod install
命令时会引起许多操做。要想深刻了解这个命令执行的详细内容,能够在这个命令后面加上 --verbose
。如今运行这个命令 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 的语法格式感到奇怪过,那是由于这是用 Ruby 语言写的。相较而言,这要比现有的其余格式更加简单好用一些。
在安装期间,第一步是要弄清楚显示或隐式的声明了哪些第三方库。在加载 podspecs 过程当中,CocoaPods 就创建了包括版本信息在内的全部的第三方库的列表。Podspecs 被存储在本地路径 ~/.cocoapods
中。
CocoaPods 使用语义版本控制 - Semantic Versioning 命名约定来解决对版本的依赖。因为冲突解决系统创建在非重大变动的补丁版本之间,这使得解决依赖关系变得容易不少。例如,两个不一样的 pods 依赖于 CocoaLumberjack 的两个版本,假设一个依赖于 2.3.1
,另外一个依赖于 2.3.3
,此时冲突解决系统可使用最新的版本 2.3.3
,由于这个能够向后与 2.3.1
兼容。
但这并不老是有效。有许多第三方库并不使用这样的约定,这让解决方案变得很是复杂。
固然,总会有一些冲突须要手动解决。若是一个库依赖于 CocoaLumberjack 的 1.2.5
,另一个库则依赖于 2.3.1
,那么只有最终用户经过明确指定使用某个版原本解决冲突。
CocoaPods 执行的下一步是加载源码。每一个 .podspec
文件都包含一个源代码的索引,这些索引通常包裹一个 git 地址和 git tag。它们以 commit SHAs 的方式存储在 ~/Library/Caches/CocoaPods
中。这个路径中文件的建立是由 Core gem 负责的。
CocoaPods 将依照 Podfile
、.podspec
和缓存文件的信息将源文件下载到 Pods
目录中。
每次 pod install
执行,若是检测到改动时,CocoaPods 会利用 Xcodeproj gem 组件对 Pods.xcodeproj
进行更新。若是该文件不存在,则用默认配置生成。不然,会将已有的配置项加载至内存中。
当 CocoaPods 往工程中添加一个第三方库时,不只仅是添加代码这么简单,还会添加不少内容。因为每一个第三方库有不一样的 target,所以对于每一个库,都会有几个文件须要添加,每一个 target 都须要:
.xcconfig
文件.xcconfig
文件prefix.pch
文件dummy.m
一旦每一个 pod 的 target 完成了上面的内容,整个 Pods
target 就会被建立。这增长了相同文件的同时,还增长了另外几个文件。若是源码中包含有资源 bundle,将这个 bundle 添加至程序 target 的指令将被添加到 Pods-Resources.sh
文件中。还有一个名为 Pods-environment.h
的文件,文件中包含了一些宏,这些宏能够用来检查某个组件是否来自 pod。最后,将生成两个承认文件,一个是 plist
,另外一个是 markdown
,这两个文件用于给最终用户查阅相关许可信息。
直到如今,许多工做都是在内存中进行的。为了让这些成果能被重复利用,咱们须要将全部的结果保存到一个文件中。因此 Pods.xcodeproj
文件被写入磁盘,另外两个很是重要的文件:Podfile.lock
和 Manifest.lock
都将被写入磁盘。
这是 CocoaPods 建立的最重要的文件之一。它记录了须要被安装的 pod 的每一个已安装的版本。若是你想知道已安装的 pod 是哪一个版本,能够查看这个文件。推荐将 Podfile.lock 文件加入到版本控制中,这有助于整个团队的一致性。
这是每次运行 pod install
命令时建立的 Podfile.lock
文件的副本。若是你碰见过这样的错误 沙盒文件与 Podfile.lock 文件不一样步 (The sandbox is not in sync with the Podfile.lock)
,这是由于 Manifest.lock 文件和 Podfile.lock
文件不一致所引发。因为 Pods
所在的目录并不总在版本控制之下,这样能够保证开发者运行 app 以前都能更新他们的 pods,不然 app 可能会 crash,或者在一些不太明显的地方编译失败。
若是你已经依照咱们的建议在系统上安装了 xcproj,它会对 Pods.xcodeproj
文件执行一下 touch
以将其转换成为旧的 ASCII plist 格式的文件。为何要这么作呢?虽然在好久之前就不被其它软件支持了,可是 Xcode 仍然依赖于这种格式。若是没有 xcproj,你的 Pods.xcodeproj
文件将会以 XML 格式的 plist 文件存储,当你用 Xcode 打开它时,它会被改写,并形成大量的文件改动。
运行 pod install
命令的最终结果是许多文件被添加到你的工程和系统中。这个过程一般只须要几秒钟。固然没有 Cocoapods 这些事也均可以完成。只不过所花的时间就不只仅是几秒而已了。
CocoaPods 和持续集成在一块儿很是融洽。虽然持续集成很大程度上取决于你的项目配置,但 Cocoapods 依然能很容易地对项目进行编译。
若是 Pods 文件夹和里面的全部内容都在版本控制之中,那么你不须要作什么特别的工做,就可以持续集成。咱们只须要给 .xcworkspace
选择一个正确的 scheme 便可。
若是你的 Pods
文件夹不受版本控制,那么你须要作一些额外的步骤来保证持续集成的顺利进行。最起码,Podfile
文件要放入版本控制之中。另外强烈建议将生成的 .xcworkspace
和 Podfile.lock
文件归入版本控制,这样不只简单方便,也能保证所使用 Pod 的版本是正确的。
一旦配置完毕,在持续集成中运行 CocoaPods 的关键就是确保每次编译以前都执行了 pod install
命令。在大多数系统中,例如 Jenkins 或 Travis,只须要定义一个编译步骤便可 (实际上,Travis 会自动执行 pod install
命令)。对于 Xcode Bots,在书写这篇文章时咱们还没能找到很是流畅的方式,不过咱们正朝着解决方案努力,一旦成功,咱们将会当即分享。
CocoaPods 简化了 Objective-C 的开发流程,咱们的目标是让第三方库更容易被发现和添加。了解 CocoaPods 的原理能让你作出更好的应用程序。咱们沿着 CocoaPods 的整个执行过程,从载入 specs 文件和源代码、建立 .xcodeproj
文件和全部组件,到将全部文件写入磁盘。因此接下来,咱们运行 pod install --verbose
,静静观察 CocoaPods 的魔力如何显现。