前言

经常使用CocoaPods来管理iOS项目中的第三方库,但是我们要使用CocoaPods来管理第三方库,前提是要写好Podfile文件,通过这个文件来配置第三方库与项目之间的依赖、版本等信息。

但是,我相信很少有人完整地学习过Podfile的语法规则,包括笔者在写本篇文章之前。今天,请大家与笔者一起来完整地学习Podfile官方教程。

之前一直想写来着,因为包括笔者在内并没有深入学习过它的使用。如果对之不够了解,如何能做到善用之。因此,下面一起来探讨探讨吧!

什么是Podfile

官方只有一句话说明什么是Podfile:The Podfile is a specification that describes the dependencies of the targets of one or more Xcode projects.

大概意思是:Podfile文件是一种规则描述,用于描述一或多个Xcode工程的targets之间的依赖。

Podfile可以很简单:

1
2
3
4
 
target 'MyApp'
pod 'AFNetworking', '~> 1.0'
 

也可以很复杂:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
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.pod_targets.each do |target|
    puts "#{target.name}"
  end
end
 

这里只是抛砖引玉,继续往下看,如何一点点地掌握Podfile的语法规则。

Podfile全局配置

目前根据官方文档说明,Podfile全局配置只有一个命令:

1
2
3
 
install!
 

官方说明它的作用是:Specifies the installation method to be used when CocoaPods installs this Podfile.(大概意思是:指定CocoaPods安装Podfile时所使用的安装方法)

例如:

1
2
3
4
5
 
install! 'cocoapods',
         :deterministic_uuids => false,
         :integrate_targets => false
 

目前支持的key有:

1
2
3
4
5
6
7
8
9
10
11
 
:clean
 
:deduplicate_targets
 
:deterministic_uuids
 
:integrate_targets
 
:lock_pod_sources
 

这个没有见过任何工程里边有人使用过,相信99%的人儿都是使用默认的全局配置。对于这几个key,官方也没有明确说明其功能!

在我们日常开发中,我们可能永远不需要使用到此配置命令,因此大家不用太关注它!

Dependencies(依赖)

CocoaPods就是用于管理第三方依赖的。我们通过Podfile文件配置来指定工程中的每个target之间与第三方之间的依赖。

有以下三个命令来管理依赖:

  • pod 指定特定依赖。比如指定依赖AFNetwroking
  • podspec 提供简单的API来创建podspec
  • target 在我们的工程中,通过target指定所依赖的范围。

Pod命令

此命令用于指定工程的依赖。我们通过Pod命令指定所依赖的第三方及第三方库的版本范围。

永远使用最新版本

1
2
3
 
pod 'HYBMasonryAutoCellHeight'
 

当我们永远使用远程仓库中的最新版本时,我们只需要指定仓库名即可。当有新的版本发布时,执行pod update命令,会更新至最新的版本。

因为版本之间可能会存在很大的差异,因此我们不应该采用这种方式,而是指定版本范围或者指定特定版本。

使用固定版本

1
2
3
 
pod 'HYBLoopScrollView', '2.0'
 

当我们不希望版本更新,而是固定使用指定的版本时,我们应该这么写法。当远程有新的版本发布时,pod是不会去更新新版本的。由于版本变化可能较大,因此有时候我们希望这么做的。

指定版本范围

1
2
3
 
pod 'HYBUnicodeReadable', '~>1.1.0'
 

当我们不要求固定版本号,而是指定某个范围时,我们会像上面这么写法。我相信大家在工程中见到最多的就是这种写法了吧。但是,我相信很多朋友并不知道这么写法的意思是什么。

它的意思是:HYBUnicodeReadable的版本可以是1.1.0到2.0.0,但是不包括2.0.0。

使用这种写法是很有用的,因此小版本的升级一般是fix bug,当有bug被fix时,我们确实应该更新。从1.9.9升级到2.0.0时,不会去更新到2.0.0版本。我们认为从2.0.0是一个大版本,大 版本的发布,通常不是fix bug,而是增加功能或者改动较大。

那么有哪些符号可以指定范围呢:

  • >= version 要求版本大于或者等于version,当有新版本时,都会更新至最新版本
  • < version 要求版本小于version,当超过version版本后,都不会再更新
  • <= version 要求版本小于或者等于version,当超过version版本后,都不会再更新
  • ~> version 比如上面说明的version=1.1.0时,范围在[1.1.0, 2.0.0)。注意2.0.0是开区间,也就是不包括2.0.0。

使用本地库

1
2
3
 
pod 'AFNetworking', :path => '~/Documents/AFNetworking'
 

如果我们的库是在本地的,那么我们可以通过这样的命令来指定。由于是引用目录,因此外部直接修改目录中的内容,CocoaPods也会更新到最新的,所以也挺不错的!

通过仓库的podspec引入

Sometimes you may want to use the bleeding edge version of a Pod. Or a specific revision. If this is the case, you can specify that with your pod declaration.

当我们需要使用库的混合边缘版本,或者指定的修订版本,我们可以通过指定像下面这样的声明。

使用仓库的master(主干):

1
2
3
 
pod 'AFNetworking', :git => 'https://github.com/gowalla/AFNetworking.git'
 

不是使用master,而是使用指定的分支:

1
2
3
 
pod 'AFNetworking', :git => 'https://github.com/gowalla/AFNetworking.git', :branch => 'dev'
 

使用指定的tag(标签,发布库的版本时,通常版本号与tag号是一致的):

1
2
3
 
pod 'AFNetworking', :git => 'https://github.com/gowalla/AFNetworking.git', :tag => '0.7.0'
 

使用指定的提交版本:

1
2
3
 
pod 'AFNetworking', :git => 'https://github.com/gowalla/AFNetworking.git', :commit => '082f8319af'
 

官方明确说明要求podspec在根目录下:

The podspec file is expected to be in the root of the repository, if this library does not have a podspec file in its repository yet, you will have to use one of the approaches outlined in the sections below.

也就是说与工程同级!比如AFNetworking中的podspec文件与库目录是同级的,都在根目录下!

从外部podspec引入

1
2
3
 
pod 'JSONKit', :podspec => 'https://example.com/JSONKit.podspec'
 

如上,当我们发布到CocoaPods时,如果没有podspec不是在根目录下,而是在外部,可以通过’:podspec’命令来指定外部链接。

podspec

Use just the dependencies of a Pod defined in the given podspec file. If no arguments are passed the first podspec in the root of the Podfile is used. It is intended to be used by the project of a library. Note: this does not include the sources derived from the podspec just the CocoaPods infrastructure.

大概意思是:使用给定的podspec所指定的pod依赖。如果没有指定参数,根目录下的podspec会被使用。

正常情况下,我们并不需要指定,一般所开源出来的库的podspec都是在根目录下,所以可放心地使用,不用考虑太多。

例如:

1
2
3
4
5
6
7
8
9
10
 
// 不指定表示使用根目录下的podspec,默认一般都会放在根目录下
podspec
 
// 如果podspec的名字与库名不一样,可以通过这样来指定
podspec :name => 'QuickDialog'
 
// 如果podspec不是在根目录下,那么可以通过:path来指定路径
podspec :path => '/Documents/PrettyKit/PrettyKit.podspec'
 

target

Defines a CocoaPods target and scopes dependencies defined within the given block. A target should correspond to an Xcode target. By default the target includes the dependencies defined outside of the block, unless instructed not to inherit! them.

大概意思是:在给定的块内定义pod的target(Xcode工程中的target)和指定依赖的范围。一个target应该与Xcode工程的 target有关联。默认情况下,target会包含定义在块外的依赖,除非指定不使用inherit!来继承(说的是嵌套的块里的继承问题)

例子:

  1. 我们指定HYBTestProject这个target可以访问HYBMasonryAutoCellHeight库:
1
2
3
4
5
 
target 'HYBTestProject' do
  pod 'HYBMasonryAutoCellHeight', '~>1.1.0'
end
 
  1. 指定HYBTestProject这个target可以访问SSZipArchive,但是它不能访问Nimble;但 是,HYBTestProjectTests这个target可以访问Nimble,默认是继承块外的,而且这里指定了inherit!继承,因此它也能 访问SSZipArchive:
1
2
3
4
5
6
7
8
9
10
 
target 'HYBTestProject' do
  pod 'SSZipArchive'
 
  target 'HYBTestProjectTests' do
    inherit! :search_paths
    pod 'Nimble'
  end
end
 
  1. target块内可以有多个target子块:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
target 'ShowsApp' do
  pod 'ShowsKit'
 
  # 可以访问ShowsKit + ShowTVAuth,其中ShowsKit是继承于父层的
  target 'ShowsTV' do
    pod 'ShowTVAuth'
  end
 
  # 可以访问Specta + Expecta
  # 同时也可以访问ShowsKit,它是明确指定继承于父层的所有pod
  target 'ShowsTests' do
    inherit! :search_paths
    pod 'Specta'
    pod 'Expecta'
  end
end
 

注意:Inheriting only search paths。也就是说inherit! :search_paths这是固定的写法。

Target configuration

这里的配置会使用和控制工程的生成。

platform

1
2
3
4
 
platform :ios, '7.0'
platform :ios
 

如果没有指定版本,官方默认值说明如下:

CocoaPods provides a default deployment target if one is not specified. The current default values are 4.3 for iOS, 10.6 for OS X, 9.0 for tvOS and 2.0 for watchOS.

也就是说,若不指定平台版本,各平台默认值如下:

  • iOS:4.3
  • OS X:10.6
  • tvOS:9.0
  • watchOS:2.0

project

默认情况下是没有指定的,当没有指定时,会使用Podfile目录下与target同名的工程:

1
2
3
4
5
6
7
8
9
10
11
12
13
 
# MyGPSApp只有在FastGPS工程中才会链接
target 'MyGPSApp' do
  project 'FastGPS'
  ...
end
 
# MyNotesApp这个target只有在FastNotes工程中才会链接
target 'MyNotesApp' do
  project 'FastNotes'
  ...
end
 

一般情况下,我们不指定project,直接使用:

1
2
3
4
5
 
target 'MyApp' do
   pod ...
end
 

inhibit_all_warnings!

inhibit_all_warnings!命令是不显示所引用的库中的警告信息。我们可以指定全局不显示警告信息,也可以指定某一个库不显示警告信息:

1
2
3
 
pod 'SSZipArchive', :inhibit_warnings => true
 

use_frameworks!

通过指定use_frameworks!要求生成的是framework而不是静态库。

workspace

默认情况下,我们不需要指定,直接使用与Podfile所在目录的工程名一样就可以了。如果要指定另外的名称,而不是使用工程的名称,可以这样指定:

1
2
3
 
workspace 'MyWorkspace'
 

source

source是指定pod的来源。如果不指定source,默认是使用CocoaPods官方的source。通常我们没有必要添加。

1
2
3
4
5
6
7
 
// 如果不想使用官方的,而是在别的地方也有,可以这样指定
source 'https://github.com/artsy/Specs.git'
 
// 默认是官方的source
source 'https://github.com/CocoaPods/Specs.git'
 

Hooks

Hooks可以叫它为勾子吧,与swizzling特性差不多,就是在某些操作之前,先勾起,而且让它执行我们特定的操作。

plugin

Specifies the plugins that should be used during installation.

Use this method to specify a plugin that should be used during installation, along with the options that should be passed to the plugin when it is invoked.

例如,指定在安装期间使用cocoapods-keys和slather这两个插件:

1
2
3
4
 
plugin 'cocoapods-keys', :keyring => 'Eidolon'
plugin 'slather'
 

pre_install

This hook allows you to make any changes to the Pods after they have been downloaded but before they are installed.

当我们下载完成,但是还没有安装之时,会勾起来,然后可以通过pre_install指定要做的事,做完后才进入安装阶段。

比如:在下载完成但未安装之前,我们就可以指定在干些什么:

1
2
3
4
5
 
pre_install do |installer|
  # Do something fancy!
end
 

post_install

既然有pre_install命令,自然会想到还有一个与之对应的命令。

This hook allows you to make any last changes to the generated Xcode project before it is written to disk, or any other tasks you might want to perform.

当我们安装完成,但是生成的工程还没有写入磁盘之时,我们可以指定要执行的操作。

比如,我们可以在写入磁盘之前,修改一些工程的配置:

1
2
3
4
5
6
7
8
9
 
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
 

def

我们还可以通过def命令来声明一个pod集:

1
2
3
4
5
 
def 'CustomPods'
   pod 'IQKeyboardManagerSwift'
end
 

然后,我们就可以在需要引入的target处引入之:

1
2
3
4
5
 
target 'MyTarget' do
   CustomPods
end
 

这么写的好处是:如果有多个target,而不同target之间并不全包含,那么可以通过这种方式来分开引入。

逗视项目的Podfile

下面是逗视项目的Podfile,这是经过笔者整理的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 
platform :ios, '8.0'
use_frameworks!
inhibit_all_warnings!
 
def shared_pods
  pod 'Alamofire', '~> 3.0'
  pod 'Kingfisher', '~> 1.6'
  pod 'MJRefresh'
  pod 'SDCycleScrollView','~> 1.3'
  pod 'APParallaxHeader'
  pod 'RoundImageView', '~> 1.0.1'
  pod 'StrechyParallaxScrollView', '~> 0.1'
  pod 'TextFieldEffects'
  pod 'IQKeyboardManagerSwift'
  pod 'SwiftyJSON'
  pod 'Validator'
  pod 'Qiniu', '~> 7.0'
  pod 'Google-Mobile-Ads-SDK', '~> 7.0'
end
 
 
target 'ds_ios'  do
  
  shared_pods
  
end
 

本文为【标哥的技术博客】原创出品,欢迎转载,转载时请注明出处!

玩转Podfile的更多相关文章

  1. 玩转spring boot——快速开始

    开发环境: IED环境:Eclipse JDK版本:1.8 maven版本:3.3.9 一.创建一个spring boot的mcv web应用程序 打开Eclipse,新建Maven项目 选择quic ...

  2. [C#] 软硬结合第二篇——酷我音乐盒的逆天玩法

    1.灵感来源: LZ是纯宅男,一天从早上8:00起一直要呆在电脑旁到晚上12:00左右吧~平时也没人来闲聊几句,刷空间暑假也没啥动态,听音乐吧...~有些确实不好听,于是就不得不打断手头的工作去点击下 ...

  3. [C#] 了解过入口函数 Main() 吗?带你用批处理玩转 Main 函数

    了解过入口函数 Main() 吗?带你用批处理玩转 Main 函数 目录 简介 特点 方法的参数 方法的返回值 与批处理交互的一个示例 简介 我们知道,新建一个控制台应用程序的时候,IDE 会同时创建 ...

  4. 玩转spring boot——开篇

    很久没写博客了,而这一转眼就是7年.这段时间并不是我没学习东西,而是园友们的技术提高的非常快,这反而让我不知道该写些什么.我做程序已经有十几年之久了,可以说是彻彻底底的“程序老炮”,至于技术怎么样?我 ...

  5. 玩转spring boot——结合redis

    一.准备工作 下载redis的windows版zip包:https://github.com/MSOpenTech/redis/releases 运行redis-server.exe程序 出现黑色窗口 ...

  6. 玩转spring boot——AOP与表单验证

    AOP在大多数的情况下的应用场景是:日志和验证.至于AOP的理论知识我就不做赘述.而AOP的通知类型有好几种,今天的例子我只选一个有代表意义的“环绕通知”来演示. 一.AOP入门 修改“pom.xml ...

  7. 玩转spring boot——结合JPA入门

    参考官方例子:https://spring.io/guides/gs/accessing-data-jpa/ 接着上篇内容 一.小试牛刀 创建maven项目后,修改pom.xml文件 <proj ...

  8. 玩转spring boot——结合JPA事务

    接着上篇 一.准备工作 修改pom.xml文件 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=&q ...

  9. 玩转spring boot——结合AngularJs和JDBC

    参考官方例子:http://spring.io/guides/gs/relational-data-access/ 一.项目准备 在建立mysql数据库后新建表“t_order” ; -- ----- ...

随机推荐

  1. jexus5.8.2 linux x64专业版 配置https

    一.环境 1.jexus版本:Jexus/5.8.2.8 Linux专业版 内置mono版本:Mono/4.6.2.7 2.操作系统:centOs7 jexus独立版由于是免安装版并且内置mono,所 ...

  2. 一步步搭建自己的博客 .NET版(2、评论功能)

    前言 这次开发的博客主要功能或特点:    第一:可以兼容各终端,特别是手机端.    第二:到时会用到大量html5,炫啊.    第三:导入博客园的精华文章,并做分类.(不要封我)    第四:做 ...

  3. iOS开发系列--网络开发

    概览 大部分应用程序都或多或少会牵扯到网络开发,例如说新浪微博.微信等,这些应用本身可能采用iOS开发,但是所有的数据支撑都是基于后台网络服务器的.如今,网络编程越来越普遍,孤立的应用通常是没有生命力 ...

  4. [Intel Edison开发板] 04、Edison开发基于nodejs和redis的服务器搭建

    一.前言 intel-iot-examples-datastore 是Intel提供用于所有Edison开发板联网存储DEMO所需要的服务器工程.该工程是基于nodejs和redis写成的一个简单的工 ...

  5. 关于js中的this之判断this

    this绑定规则的优先级顺序 new操作符绑定 > 显示绑定 > 隐式绑定 > 默认绑定   所以在判断函数在某个调用位置应用的是哪条规则,可以按下列这样的顺序   if(函数在ne ...

  6. 初学者--bootstrap(六)组件中的下拉菜单----在路上(10)

    组件---下拉菜单 用于显示链接列表的可切换.有上下文的菜单.下拉菜单的 JavaScript 插件让它具有了交互性. 将下拉菜单触发器和下拉菜单都包裹在 .dropdown 里,或者另一个声明了 p ...

  7. SQL Server 动态生成数据库所有表Insert语句

    一. 背景 SQL Server,如果我们需要把数据库A的所有表数据到数据库B中,通常我们会怎么做呢?我会使用SSMS的导入导出功能,进行表数据的导入导出,无可厚非,这样的导入非常简单和方便: 但是, ...

  8. 关于android中调用系统拍照,返回图片是旋转90度

    转载博客:http://blog.csdn.net/walker02/article/details/8211628 项目开发中遇到的一个问题,对于三星手机在做手机照片选择时出现图片显示不正常,研究后 ...

  9. html5+go+websocket简单实例代码

    这次的就直接发放代码截图吧,应该是用go语言做后台一个简易的聊天,这里没用到什么特别的知识,最朴实的来实现效果,主要目的是分享下h5怎么用websocket,go搭建websocket服务的主要部分. ...

  10. 【Python五篇慢慢弹】数据结构看python

    数据结构看python 作者:白宁超 2016年10月9日14:04:47 摘要:继<快速上手学python>一文之后,笔者又将python官方文档认真学习下.官方给出的pythondoc ...