CocoaPods是Swift和OC项目的依赖项管理器。
Podfile是一个规范,描述一个或多个Xcode项目目标的依赖关系。
此文目的:我们经常使用CocoaPods来管理iOS项目中的第三方库,但是从来没有完整地学习过Podfile的语法规则。
本文翻译自CocoaPods官网
一、Podfile示例
大概了解下,Podfile可以设置哪些内容。
1、podfile可以简单
target 'MyApp'
pod 'AFNetworking', '~> 1.0'
2、也可以复杂
platform :ios, '9.0'
inhibit_all_warnings!
target 'MyApp' do
pod 'ObjectiveSugar', '~> 0.5'
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
二、语法介绍
1、Root Options
(1)install!
Podfile唯一的全局配置,用来指定当CocoaPods安装这个Podfile时要使用的安装方法和选项。第一个参数表示要使用的安装方法;下一个参数表示安装选项。目前,唯一接受的安装方法是“cocoapods”,因此您将始终使用该值作为第一个参数;但是更多的安装方法可能在以后的版本中可用。
install! 'cocoapods',
:deterministic_uuids => false,
:integrate_targets => false
支持的keys:
但是官方并没有解释如何用,通常也用不到install!这个命令。可以忽略,有个印象就可以了
:clean
:deduplicate_targets
:deterministic_uuids
:integrate_targets
:lock_pod_sources
:share_schemes_for_development_pods
2、依赖 Dependencies
可以指定每个target的依赖
(1)pod
①设置依赖库版本
pod 'name' ,'version'
如果想安装最新版本,那么不指定版本就好了
pod 'AFNetworking'
安装指定版本
pod 'AFNetworking', '2.4.1'
指定版本范围,也可以使用操作符:
- = 0.1 版本0.1。
- > 0.1 大于0.1的版本。
- >= 0.1 大于等于0.1的版本。
- < 0.1 小于0.1的版本。
- <= 0.1 小于等于0.1的版本。
-
~> 0.1.2 等价于>=0.12且<0.2 并且将始终匹配最新的已知版本。
如果对版本有更精细力度的要求,请参见 Semantic Versioning、 RubyGems Versioning Policies
②Build configurations
依赖项默认是安装在target所有的构建配置中。但是有时候可能只在某个环境添加依赖项,此时可以设置需要添加依赖项的构建环境列表。
#只在Debug和Beta模式下才有启用配置
pod 'PonyDebugger', :configurations => ['Debug', 'Beta']
AFNetworking只安装到debug环境
pod 'AFNetworking', :configuration => 'Debug'
③Subspecs
当通过名字安装依赖库的时候,会默认安装依赖库的所有内容,所有子模块。
安装一个特定的子模块,如下
pod 'AFNetworking/Reachability'
还可以指定安装的子模块集合
pod 'AFNetworking', :subspecs => ['Serialization', 'Security']
支持的子模块可以通过pod search查询
$ pod search AFNetworking
④安装本地依赖库
pod 'UZHybridModule', :path => '../UZHybridModule'
使用path选项之后可以从本地安装依赖库,../UZHybridModule是依赖库的本地路径,这些文件被直接引入到工程中。会被添加到Development Pods文件夹下,也就是pod的开发者模式,对依赖库代码编辑有效。
【注意】本地依赖库文件夹下要包含podspec文件
⑤通过仓库根目录下的podspec引入
使用master分支
pod 'AFNetworking', :git => 'https://github.com/gowalla/AFNetworking.git'
指定分支,比如dev
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 => '082f8319af'
⑥依赖库没有独立podspec的情况
如果一个依赖库的podspec来自另一个源
pod 'JSONKit', :podspec => 'https://example.com/JSONKit.podspec'
(2)podspec
如果不给podspec设置参数,那么默认使用根目录下的podspec。
# 不传参数表示使用根目录下的podspec,默认一般都会放在根目录下
podspec
#如果podspec名与依赖库名不相同的话,使用这个指定name
podspec :name => 'QuickDialog'
#如果podspec不在根目录的,需要设置path
podspec :path => '/Documents/PrettyKit/PrettyKit.podspec'
(3)target
在给定的块内定义target以及依赖的范围,target与Xcode中的target是对应的。默认情况下target包含定义在块之外的依赖,除非指明不继承 。
可以结合下文中 多个子模块嵌套的情况 进行理解
target 'target名'
定义一个target
target 'ZipApp' do
pod 'SSZipArchive'
end
定义一个从其父节点访问SSZipArchive 的测试target(ZipAppTests)
ZipApp 只引入SSZipArchive,ZipAppTests会引入SSZipArchive和Nimble
target 'ZipApp' do
pod 'SSZipArchive'
target 'ZipAppTests' do
inherit! :search_paths
pod 'Nimble'
end
end
多个子模块嵌套的情况
target 'ShowsApp' do
pod 'ShowsKit'
# 拥有 ShowsKit 和 ShowTVAuth
target 'ShowsTV' do
pod 'ShowTVAuth'
end
# 拥有 Specta + Expecta + ShowsKit
target 'ShowsTests' do
inherit! :search_paths
pod 'Specta'
pod 'Expecta'
end
end
(4)abstract_target
定义一个抽象target,方便其他target继承
abstract_target 'target名'
定义一个抽象target
abstract_target 'Networking' do
pod 'AlamoFire'
target 'Networking App 1'
target 'Networking App 2'
end
定义一个包含多个target的抽象target
# Note: There are no targets called "Shows" in any of this workspace's Xcode projects
#在项目中并没有一个叫Shows的target,这里可以随便起一个名字。
abstract_target 'Shows' do
pod 'ShowsKit'
# The target ShowsiOS has its own copy of ShowsKit (inherited) + ShowWebAuth (added here)
#ShowsiOS自己拥有ShowsKit(继承的)+ShowWebAuth (通过pod添加的)
target 'ShowsiOS' do
pod 'ShowWebAuth'
end
# The target ShowsTV has its own copy of ShowsKit (inherited) + ShowTVAuth (added here)
#ShowsTV自己拥有ShowsKit (继承的) + ShowTVAuth (通过pod添加的)
target 'ShowsTV' do
pod 'ShowTVAuth'
end
# 测试target有自己添加的Specta+ Expecta,也能访问ShowsKit,因为他是抽象 Shows的子target。
target 'ShowsTests' do
inherit! :search_paths
pod 'Specta'
pod 'Expecta'
end
end
(5)abstract!
表示当前目标是抽象的,因此不会直接链接到Xcode目标。
(6)inherit!
设置当前target的继承模式。
inherit! mode
-
mode的值:
:complete 继承父类的所有行为。
:none 不继承父类的行为
:search_paths 只继承父类的搜索路径,官方没有给更过的解释,个人觉得这里对应build setting中的search path。
3、Target configuration
这些设置用于控制cocoapods生成的项目。
最简单的 只需说明你所需的platform。xcodeproj允许指定要链接的项目。
(1)platform
指定构建静态库的平台。
platform name , target
支持的参数
name : symbol类型平台的名称
值可以是:
:osx 代表OS X,
:ios 代表 iOS,
:tvos 代表tvOS,
:watchos 代表watchOS。target: string类型,可选值,对应Xcode中的deployment target,也就是我们最低适配版本。
当前默认值为iOS 4.3,OS X 10.6,tvOS 9.0,watchOS 2.0。
如果部署目标要求(iOS < 4.3),那么armv6架构将被添加到ARCHS中。
#iOS平台,适配最低版本为4.0·
platform :ios, '4.0'
platform :ios
(2)project
指定Xcode project,该project包含了链接pod库的target。
如果target没有指明project,并且Podfile所在目录下只有一个project,那么这个project就会被使用。也可以设置build setting在release或是debug情况下如何配置。要做到这一点,你需要将每个build configuration的名字与:release或是:debug关联
project path, build_configurations
支持的参数
- path : project路径
- build_configurations : 是Hash{String => symbol}这种格式的哈希值,key是Xcode project中build configuration的名字,value是 :debug 或者 :release。不指定默认 :release
指明project
# This Target can be found in a Xcode project called `FastGPS`
#这个目标可以在一个名为“FastGPS”的Xcode项目中找到
target 'MyGPSApp' do
project 'FastGPS'
...
end
# Same Podfile, multiple Xcodeprojects
#多个Xcodeprojects Podfile相同,
target 'MyNotesApp' do
project 'FastNotes'
...
end
使用自定义build configuration
project 'TestProject', 'Mac App Store' => :release, 'Test' => :debug
(3)被废弃的命令
xcodeproj在1.0中被弃用,并被重命名为project。对于1.0之前的版本,使用xcodeproj。
link_with在1.0中被弃用,被abstract_target和inheritance 代替。
(4)inhibit_all_warnings!
屏蔽所有cocoapods的警告。
可以全局设置,也可以屏蔽某个pod的警告。
pod 'SSZipArchive', :inhibit_warnings => true
全局设置之后,也可以设置某个pod不屏蔽警告。
pod 'SSZipArchive', :inhibit_warnings => false
(5)use_frameworks!
生成动态库而不是静态库
此属性被target定义继承。
使用use_frameworks与不使用,生成的库文件如下所示
target 'runtime' do
# Uncomment the next line if you're using Swift or would like to use dynamic frameworks
# use_frameworks!
# Pods for runtime
pod 'AFNetworking', :subspecs => ['Serialization', 'Security']
end
target 'runtime' do
# Uncomment the next line if you're using Swift or would like to use dynamic frameworks
use_frameworks!
# Pods for runtime
pod 'AFNetworking', :subspecs => ['Serialization', 'Security']
end
`
4、Workspace
接下来讲述配置Workspace和设置全局设置的选项。
(1)workspace
用于指定workspace。如果没有指定明确的workspace,并且在Podfile同一个目录中只有一个project,那么该项目的名称就被用作workspace的名称。
workspace path
path:workspace的路径,通常都是在Podfile同一个目录下
#如果workspace名不是工程名,可以如下指定
workspace 'MyWorkspace'
(2)generate_bridge_support!
没用过,看到知道是什么意思就可以了。
指明BridgeSupport元数据文档应该从所有安装的pod库头文件中生成。
这是用于脚本语言,如MacRuby、Nu和JSCocoa,它们使用它来桥接类型、函数等。
(3)set_arc_compatibility_flag!
现在应该用不到了。
指明-fobjc-arc要被添加到OTHER_LD_FLAGS中
用来解决Xcode 4.3.2的libtool不再支持- fobjc- arc标志的问题,需要使用这种方式显式启用它。
5、Sources
全局配置source信息,用于指定specs的位置
source 'URL'
使用这个方法指定source,source列表的顺序决定读取顺序,会读取第一个包含我们需要pod的source,并且使用pod的最高版本,不管其他源是不是有更高的版本。
指定第一个使用artsy的源。因为CocoaPods的源是隐式,指定了其他的源之后就需要显示包含一下。
CocoaPods Master Repository
source 'https://github.com/artsy/Specs.git'
source 'https://github.com/CocoaPods/Specs.git'
6、Hooks
Podfile提供在安装过程中调用的钩子。
钩子是全局的,不存储在任何一个target定义中
(1)plugin
使用此方法来指定在安装期间应该使用的插件,以及当插件被调用时应该传递的参数。
plugin name ,options
name: String类型,插件名称
options: Hash类型,可选值。当插件的钩子被调用时用来传递参数。
#指定使用“slather”和“cocoapods - keys”插件。
plugin 'cocoapods-keys', :keyring => 'Eidolon'
plugin 'slather'
(2)pre_install
这个钩子允许你在Pods下载完成后且安装之前对Pods进行修改。
只接受Pod::Installer作为参数
#在Podfile中定义预安装钩子。
pre_install do |installer|
# Do something fancy!
end
(3)post_install
这个钩子允许你在Xcode项目写入磁盘之前做最后的修改,或者执行一些其他的任务。
只接受Pod::Installer作为参数
#定制所有目标的构建设置
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['GCC_ENABLE_OBJC_GC'] = 'supported'
end
end
end
以上只是参照官方文档结合自己的理解写的,如果有不正确的地方,或者是有更深层次的理解,欢迎留言交流。