CocoaPods入门
CocoaPods是什么
CocoaPods是一个用来管理Xcode项目依赖库的工具。
你的项目依赖库需要被详细列在一个叫Profile的文件中。CocoaPods将帮我们解决libraries之间的依赖关系、获取目标库的源码、并将它链接到Xcode workspace中来构建你的项目。
最终目标是通过建立一个查找效率更高、更规范的第三方开源库生态系统。
安装CocoaPods
CocoaPods是基于Ruby开发的,通过OS X 默认可用的Ruby安装。
$ sudo gem install cocoapods
在安装过程中遇到任何问题,请查看此处。
升级CocoaPods
只要再执行安装gem命令就可以升级你的CocoaPods
$ [sudo] gem install cocoapods // 正式发布版本
可以使用如下命令来更新到预发布版本,如果预发布版本存在的话
$ [sudo] gem install cocoapods --pre // 预发布版本
如果你在安装时使用了sudo,那你应该再次使用这个命令。
之后,在你使用Cocoapods安装依赖库的时候,如果有新版CocoaPods时,你就会收到通知告知你CocoaPods X.X.X已经用了,请更新的信息。
使用CocoaPods
在已有项目中使用CocoaPods
前提
- 已经安装CocoaPods
- 通过Specs仓库或cocoapods.org确定将要被引用的资源是可用的
第一步、创建Podfile文件,并添加依赖库。
target 'MyApp' do
pod 'AFNetworking', '~> 3.0'
pod 'FBSDKCoreKit', '~> 4.9'
end
第二步、终端进入Podfile文件所在目录,运行pod install
pod install
第三步、打开新生成的**.xcworkspace文件,继续开发。
使用CocoaPods创建一个新项目
使用CocoaPods创建一个新项目,步骤如下:
第一步、正常创建一个项目
第二步、通过终端进入项目目录。
$ cd your project directory
第三步、创建Podfile。
$ pod init
第四步、创建Podfile,可以通过pod init命令创建。
$ pod init
首先 输入平台及版本,如:platform :ios, ‘9.0’
其次 指定项目。以target ‘$TARGET_NAME’ do开始,以end结束。
- 而后 添加依赖资源。pod ‘$PODNAME’
target 'MyApp' do
pod 'ObjectiveSugar'
end
第五步、保存Podfile,终端运行
$ pod install
第六步、打开新创建的 MyApp.xcworkspace文件,以后每次打开项目都是这种方式。
在已有workspace中使用CocoaPods
在Podfile文件中加入一行信息,指定workspace。
workspace 'MyWorkspace'
什么时候使用pod install 什么时候使用pod update?
很多人对于什么时候使用pod install 什么时候使用pod update有困惑,尤其当本该使用pod install的时候他们却使用了pod update。
你可以在这篇专题文章中找到具体解释何时使用他们,并且使用他们的目的。
是否需要将Pods目录加入代码版本管理?
是否将你的Pods文件夹加入版本管理取决于你,因为每个项目的工作流是不同的。我们建议你将Pods目录进行版本控制,不要把它加入到.gitignore文件中,但是最终这取决于你。
将Pods目录加入版本管理的好处
在科隆仓库后,项目可以立即被构建和运行,甚至不需要在本机上安装CocoaPods。不需要运行pod install,也不需要网络。
pod里的工具(代码和库)都是可用的,即便一个pod的源连接不上。
在科隆后可以确保Pod里的工具跟执行过pod install的人的一模一样。
忽略Pods目录的好处
版本控制仓库占用的磁盘空间更少更小。
当所有的pods可以使用时,CocoaPods将可以再次创建相同的安装。(技术上当在Podfile中不使用提交SHA值的时候不能确保执行pod install命令将获取或者重新创建一样的工具)
当执行版本控制操作时不会有任何冲突,比如在不同pod版本中执行合并分支。
无论是否加入版本管理,Podfile和Podfile.lock都应当加入版本控制。
What is Podfile.lock?
当第一次执行pod install的时候会生成这个文件,它会跟踪已经安装的每个pod,比如,下面的依赖列在Podfile里:
pod 'RestKit'
执行pod install命令将安装当前版本的RestKit,并生成Podfile.lock并列出确切安装的版本(比如 RestKit 0.10.3)。多亏podifle.lock,这样我们随后在其他机器上执行pod install会安装 RestKit 0.10.3,即便有其他的新版本可以使用。CocoaPods将会在Podfile.lock中标记Pod版本,除非在podfile里更新了依赖或者执行了pod update命令(它将生成的新的Podfile.lock)。通过这个方式CocoaPods避免了意外的依赖更改导致的问题。
使用CocoaPods时,背后究竟发生了什么
在Xcode中,直接可以引用ruby源,它将:
- 创建并更新一个workspace.
- 如果需要的话将你的项目加入到workspace。
- 如果需要将CocoaPods静态库项目加入到workspace。
- 将libPods.a添加到库的targets => build phases => link。
- 将CocoaPods的Xcode配置添加到你的app’s项目中。
- 修改你APP项目的target配置为基于CocoaPod的。
- 将你安装的到你APP项目的所有的pod中的资源文件拷贝添加到build phase。比如其他build phase后的‘Script build phase’,如下:
- Shell: /bin/sh
- Script: ${SRCROOT}/Pods/PodsResources.sh
Note that steps 3 onwards are skipped if the CocoaPods static library is already in your project. This is largely based on Jonah Williams’ work on Static Libraries.
注意上面的步骤3将会被跳过,如果CocoaPods静态库已经在你的项目的话,这很大一部分是由Jonah Williams处理静态库的方式导致。
从子模块迁移到Pods
CocoaPods和git 子模块都是为了解决相似的问题。他们都致力于简化第三方库代码的处理流程。子模块指向某个项目的特定提交,然而CocoaPods则和版本了的开发者发布版关联在一起。
从子模块切换到CocoaPods
在你决定是否完全切换到CocoaPods时,确保你当前使用的库可用。记录你当前使用的库的版本想法的对的。这样你可以使用一样的库来初始化CocoaPods。最好逐步使用他们,通过一个依赖一个依赖去做而不是一个大的改变。
- 如果你没有安装CocoaPods的话先安装一下。
- 创建Podfile文件。
- 移除子模块的引用。
- 在Podfile中添加删除库的引用
- 执行pod install
Podfile文件精讲
Podfile文件是描述一个或者多个Xcode项目target的依赖的详细说明。这个文件必须命名为Podfile。下文和之前的的例子是基于CocoaPods 1.0版本。
一个简单的podfile文件
target 'MyApp' do
pod 'AFNetworking', '~> 3.0'
end
一个复杂的podfile文件管理一个APP和他一个测试工程(bundle)
source 'https://github.com/CocoaPods/Specs.git'
source 'https://github.com/Artsy/Specs.git'
platform :ios, '9.0'
inhibit_all_warnings!
target 'MyApp' do
pod 'GoogleAnalytics', '~> 3.1'
# Has it's own copy of OCMock
# and has access to GoogleAnalytics via the app
# that hosts the test target
target 'MyAppTests' do
inherit! :search_paths
pod 'OCMock', '~> 2.0.1'
end
end
post_install do |installer|
installer.pods_project.targets.each do |target|
puts target.name
end
end
如果你希望使用多个target来分享同一个pods,可以使用abstract_target。
使用abstract_target
# There are no targets called "Shows" in any Xcode projects
abstract_target 'Shows' do
pod 'ShowsKit'
pod 'Fabric'
# Has it's own copy of ShowsKit + ShowWebAuth
target 'ShowsiOS' do
pod 'ShowWebAuth'
end
# Has it's own copy of ShowsKit + ShowTVAuth
target 'ShowsTV' do
pod 'ShowTVAuth'
end
end
在Podfile根下包含一个抽象的target,因此你也可以这样写:
pod 'ShowsKit'
pod 'Fabric'
# Has it's own copy of ShowsKit + ShowWebAuth
target 'ShowsiOS' do
pod 'ShowWebAuth'
end
# Has it's own copy of ShowsKit + ShowTVAuth
target 'ShowsTV' do
pod 'ShowTVAuth'
end
从0.x到1.0的迁移
另外一篇文章深度讲解这个。
具体给出pod版本
pod 'Objection', '0.9'
- ‘> 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.2.0’
- ‘~> 0.1’ 相当于’>= 0.1 且 ‘< 1.0’
- ‘~> 0’ 相当于不写,即最新版本
使用本地路径下的文件
pod 'AFNetworking', :path => '~/Documents/AFNetworking'
使用库所在仓库根路径下的podspec
// 使用master分支
pod 'AFNetworking', :git => 'https://github.com/gowalla/AFNetworking.git'
// 使用指定分支
pod 'AFNetworking', :git => 'https://github.com/gowalla/AFNetworking.git', :branch => 'dev'
// 使用指定tag
pod 'AFNetworking', :git => 'https://github.com/gowalla/AFNetworking.git', :tag => '0.7.0'
// 使用某一次提交
pod 'AFNetworking', :git => 'https://github.com/gowalla/AFNetworking.git', :commit => '082f8319a