[iOS] CocoaPods - Podfile文件配置

前言:之前使用CocoaPods时,对于Podfile文件的配置,也就了解了最基本的使用。但是公司同事对于Podfile的配置有很多骚操作,不得不系统的了解一下了,😄!内容都翻译自官方文档:https://guides.cocoapods.org/syntax/podfile.html#podfile

1. 介绍

当我们新建一个Xcode项目之后,想要使用Cocoapods管理依赖,就需要在Xcode工程目录下执行pod init命令,这个命令的作用就是生成一个Podfile文件

生成的Podfile文件是描述我们Xcode工程中Target所有依赖的说明书,工程所有依赖的第三方pod库都需要配置到Podfile文件中。

有了Podfile文件之后,我们就可以使用pod install命令,生成workspace,将工程项目和所依赖的pod工程建立关联,这个暂且先不去研究pod install的具体过程。

2. 简单使用

新建立的Podfile文件非常简单,我们配置工程依赖AFNetworking这个第三方库,并指定了所依赖的版本,如下图所示:

# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'WKWebView' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  # Pods for WKWebView
  pod 'AFNetworking', '~> 1.0'
end

如果我们只是简单的使用Cocoapods,那么了解到此处好像也够用了,但是随着项目的不断增大,可能会有额外特殊的配置(多个target,增加额外操作)增加Podfile的复杂性,如下所示:

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

这个Podfile文件内容相比于上面那一个,算是复杂了挺多,增加了一些不认识的配置,不过这不是什么问题,这次就是来学习的。

3. Root Options 根选项

Root Options会应用于整个Podfile文件

3.1 install! (别忘了还有一个感叹号!哦)

可以使用install! 指定CocoaPods在安装这个Podfile时要使用的安装方法和安装选项,如下所示:

install! 'cocoapods',
         :deterministic_uuids => false,
         :integrate_targets => false
  • cocoapods就是我们指定的安装方法,目前也只能指定为cocoapods,以后可能支持别的。

  • :deterministic_uuids => false, :integrate_targets => false这两个是安装选项,下面会有具体说明。

下面针对一些安装选项,做一下说明,好歹先了解一部分,等用到的时候再细查。

3.1.1 :clean (默认true)

作用:标记安装过程中是否需要清理pods没有用到的数据,这些数据都是由podsepc配置和所支持平台决定的。

3.1.2 : deduplicate_targets (默认true)

作用:标记是否删除相同的pod target。

比如,两个target都依赖了同一个pod库,如下所示:

target 'MyTargetA' do
  pod 'MyPod/SubA'
  pod 'OtherPod'
end

target 'MyTargetB' do
  pod 'MyPod'
  pod 'OtherPod'
end

如果将deduplicate_targets设置为false,则会生成带后缀的两个OtherPod,一个供MyTargetA使用,一个供MyTargetB使用,但是实际上是一个东西呀,所以就需要干掉一个,让两个Target使用同一个OtherPod,就需要将deduplicate_targets设置为true

但是不会影响MyPod,因为MyTargetA使用的是子库MyTargetB 使用的是主库,所以对应会有两个MyPod的target

3.1.3 deterministic_uuids (默认true)

在创建Pods项目时是否生成确定的uuid。

在网上搜到了这个选项导致的问题:https://www.cnblogs.com/strengthen/p/14899231.html,看来一个pod库的对应标记。

3.1.4 integrate_targets (默认true)

标记是否将pods添加到项目中,如果设置为false,则只会下载到Pods/文件夹下。

3.1.5 lock_pod_sources(默认true)

标记是否对pod库中文件内容加锁,默认是加锁的,所以当我们在修改pod库中的文件时,经常会有提示是否解锁的弹窗,如下:


截屏2021-12-23 下午5.50.58.png

这个操作会对pod install有影响,可以根据实际情况考虑设置为false。

3.1.6 warn_for_multiple_pod_sources(默认true)

标记当多个源包含相同名称和版本的Pod时,是否发出警告⚠️。如果发现了这个警告,我们需要手动指定这个pod使用的源。

3.1.7 warn_for_unused_master_specs_repo(默认true)

如果项目没有明确指定基于git的master分支的spec repo,就使用默认的CDN代替,这种情况下是否发出如下警告:

[!] Your project does not explicitly specify the CocoaPods master specs repo. Since CDN is now used as the default, you may safely remove it from your repos directory via `pod repo remove master`. To suppress this warning please add `warn_for_unused_master_specs_repo => false` to your Podfile.
3.1.8 share_schemes_for_development_pods(默认false)

标记对于DevelopmentPods是否共享Xcode的schemes,默认是不会共享的,DevelopmentPods的schemes会自动创建。

3.1.9 disable_input_output_paths(默认false)

标记是否禁用CocoaPods脚本阶段的输入和输出路径 (Copy Frameworks & Copy Resources)

image.png
3.1.10 preserve_pod_file_structure(默认false)

标记是否保留所有pod的文件夹结构,包括外部的pod。默认情况下,Pod库的文件结构只保留给开发Pod使用,我们在项目中查看三方pod库时,都是放在一个文件夹中,但是在开发时是有文件夹结构的。

3.1.11 generate_multiple_pod_projects(默认false)

标记是否为每个pod库生成一个project,而不是只创建1个Pods.xcodeproj。如果设置为true,此选项将为每个将嵌套在Pods.xcodeproj下的pod库生成一个对应的project,如下图所示:


image.png

并且有文章还说,设置为true后,会提升项目的解析速度:https://www.jianshu.com/p/88c41ee40e88

3.1.12 incremental_installation(默认false)

当执行 pod install 时,CocoaPods 现在支持仅重新生成自上次 install 以来发生更改的 pod 库,而不是像之前那样重新生成整个 workspace。

设置incremental_installation 为 true 选项开启此功能,但是incremental_installation 选项需要启用 generate_multiple_pod_projects 安装选项才能使其正常运行。

3.1.13 skip_pods_project_generation(默认false)

标记是否跳过生成Pods.Xcodeproj,只执行依赖关系解析和下载,设置为true,会影响使用呀。

3.2 ensure_bundler!

使用Global Gemset运行CocoaPods时引发警告。如果bundler版本与所需版本不匹配,可以提供语义版本来发出警告。

许多项目在与 CocoaPods 一起使用时都在后台使用Bundler。这是因为 Bundler 确保了一致的环境,这对于开发同一项目的团队很有用。

在1.10.0版本之后,提供了一个新的 ensure_bundler! DSL,可以添加到 Podfile 中,以指定 Bundler 版本的版本要求。

如下:

ensure_bundler!
ensure_bundler! '~> 2.0.0'

4. Dependencies 依赖项

Podfile指定每个target的依赖项。
Pod是一种声明特定依赖的方式。
podspec为创建podspec提供了一个简单的API。
target是你在Xcode项目中的target。

4.1 pod

pod 用于指定项目的依赖项。

4.1.1 指定版本号

pod 用于指定项目的依赖项,依赖项必须指定名称,版本是可选的。

  • 没有指定版本号,则会默认使用最新的版本:
pod 'SSZipArchive'
  • 可以指定使用固定的版本:
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 版本号 >= 0 && 版本号 < 1
  • ~> 0.1.3-beta.0 Beta和发布版本为0.1.3,发布版本 >= 0.1.3 && 发布版本<0.2。用破折号(-)分隔的组件将不考虑版本要求。
4.1.2 Build configurations

默认情况下,依赖项安装在目标的所有构建配置中。如果出于调试目的或其他原因,需要只在Debug模式下启用,可以如下配置:

pod 'PonyDebugger', :configurations => ['Debug', 'Beta']

or

pod 'PonyDebugger', :configuration => 'Debug'

请注意,所有配置中都包含过渡依赖项,如果不希望这样做,必须手动指定它们的构建配置。

4.1.3 Modular Headers (模块化头文件)

如果你想使用模块头每个Pod你可以使用以下语法:

pod 'SSZipArchive', :modular_headers => true

导入时可以使用@import SSZipArchive; 进行导入。

此外,当你使用use_modular_headers!属性,你可以使用以下方法从模块头文件中排除一个特定的Pod:

pod 'SSZipArchive', :modular_headers => false
4.1.4 Source(指定源)

默认情况下,在全局级别指定的源将按照依赖项匹配指定的顺序进行搜索。对于特定的依赖,可以单独指定依赖源:

pod 'PonyDebugger', :source => 'https://github.com/CocoaPods/Specs.git'
4.1.5 Subspecs (使用子库)

当通过Pod的名称安装Pod时,它将安装podspec文件中定义的所有默认subspecs

可以使用下面的方式导入特定的subspec:

pod 'QueryKit/Attribute'

or

pod 'QueryKit', :subspecs => ['Attribute', 'QuerySet']
4.1.6 Test Specs

Test Specs可以通过:testspecs选项包含。默认情况下,Test Specs都不包括在内。

可以使用下面的方式进行导入:

pod 'AFNetworking', :testspecs => ['UnitTests', 'SomeOtherTests']
4.1.7 Using the files from a local path (使用本地路径)

如果和项目一样在本地开发Pod,可以使用path选项,如下:

pod 'AFNetworking', :path => '~/Documents/AFNetworking'

注意,Pod文件的podspec必须在该文件夹中。

4.1.8 指定分支或者commit
  • 指定源,默认是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'
  • 特殊的commit
pod 'AFNetworking', :git => 'https://github.com/gowalla/AFNetworking.git', :commit => '082f8319af'

podspec文件应该位于存储库的根目录中,如果这个库的存储库中还没有podspec文件,可以从其它来源获得:

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

4.2 podspec

只使用在给定podspec文件中定义的Pod的依赖项。如果没有传递参数,将使用Podfile根目录中的第一个podspec。它的目的是供库的项目使用。

注意:这并不包括来自podspec的源代码,只包括CocoaPods基础设施。

# 无参数
podspec
# 有参数
podspec :name => 'QuickDialog'
# 有参数
podspec :path => '/Documents/PrettyKit/PrettyKit.podspec'

4.3 target

在给定的块中定义CocoaPods的target和作用域依赖项。
一个target应该对应一个Xcode target。默认情况下,这个目标包含了块外面定义的依赖项,除非被指示不要inherit!(继承)他们。

target 'HTDemo' do
  pod 'ZZKit'
  pod 'SDWebImage'

  target 'HTDemo2' do
    inherit! :search_paths
    pod 'SDWebImage'
  end
end

HTDemo的依赖项:

截屏2021-12-23 下午8.57.09.png

HTDemo2的依赖项:

截屏2021-12-23 下午8.57.39.png

4.4 关于inherit!

设置当前目标的继承模式。

  • inherit! : complete
    继承了父对象的所有行为

  • inherit! : none
    目标不会从父对象继承任何行为

  • inherit! : search_paths
    目标只继承父节点的搜索路径

4.5 abstract_target

定义一个新的抽象目标target,可用于方便的目标依赖项继承。

# Note: There are no targets called "Shows" in any of this workspace's Xcode projects
abstract_target 'Shows' do
  pod 'ShowsKit'

  # The target ShowsiOS has its own copy of ShowsKit (inherited) + ShowWebAuth (added here)
  target 'ShowsiOS' do
    pod 'ShowWebAuth'
  end

  # The target ShowsTV has its own copy of ShowsKit (inherited) + ShowTVAuth (added here)
  target 'ShowsTV' do
    pod 'ShowTVAuth'
  end

  # Our tests target has its own copy of
  # our testing frameworks, and has access
  # to ShowsKit as well because it is
  # a child of the abstract target 'Shows'

  target 'ShowsTests' do
    inherit! :search_paths
    pod 'Specta'
    pod 'Expecta'
  end
end

abstract!表示当前目标是抽象的,因此不会直接链接到Xcode目标,暂未看到更多描述,应该也用不到这个。

5. Target configuration

这些设置用于控制CocoaPods生成的项目,首先要说明你正在开发的平台。xcodeproj允许您指定要链接的项目。

5.1 platform

指定应该为其构建静态库的平台。

# 也可以是:osx :iOS :tvOS :watchos
platform :ios, '9.0'
platform :ios

5.2 project

指定Xcode项目,该项目包含了Pods库应该链接的目标target。

如果没有指定project,并且与Podfile相同的目录中只有一个project,那么将使用该project。

# This Target can be found in a Xcode project called `FastGPS`
target 'MyGPSApp' do
  project 'FastGPS'
  ...
end

# Same Podfile, multiple Xcodeprojects
target 'MyNotesApp' do
  project 'FastNotes'
  ...
end

5.3 inhibit_all_warnings!

去掉CocoaPods库中的所有警告。

也可以针对单个pod特殊指定:

pod 'SSZipArchive', :inhibit_warnings => true

5.4 use_modular_headers!

为所有CocoaPods静态库使用模块化头文件。

也可以针对单个pod特殊指定:

pod 'SSZipArchive', : use_modular_headers => true

5.5 use_frameworks!

使用frameworks而不是静态库。当使用frameworks时,你也可以指定:linkage样式来使用,比如:static或:dynamic。

此属性可以由子目标target定义继承。

target 'MyApp' do
  use_frameworks!
  pod 'AFNetworking', '~> 1.0'
end
target 'MyApp' do
  use_frameworks! :linkage => :dynamic
  pod 'AFNetworking', '~> 1.0'
end

target 'ZipApp' do
  use_frameworks! :linkage => :static
  pod 'SSZipArchive'
end

5.6 supports_swift_versions

指定此目标定义支持的Swift版本要求。

注意:这些需求可以从父级继承的,如果没有指定,那么所有的版本都被认为是支持的。

supports_swift_versions '>= 3.0', '< 4.0'

target 'MyApp' do
  pod 'AFNetworking', '~> 1.0'
end

target 'ZipApp' do
  pod 'SSZipArchive'
end

6. Workspace

6.1 workspace

指定包含所有项目的Xcode工作区。

workspace 'MyWorkspace'

如果没有明确指定Xcode工作空间,并且只有一个项目存在于与Podfile相同的目录中,那么这个项目的名称将被用作工作空间的名称。

7. Sources

Podfile从给定的源代码(存储库)列表中检索规范,源是全局的,它们不是按目标定义存储的。

一般都是写到podfile文件最顶部:

source 'https://github.com/artsy/Specs.git'
source 'https://github.com/CocoaPods/Specs.git'

注意事项:

  • 使用此方法会依赖于来源的顺序。CocoaPods将使用包含Pod的第一个来源的Pod的最高版本(无论其他来源是否有更高的版本)。
  • 如果指定了别的源,也需要将官方的源写一下

8. Hooks

Podfile提供将在install过程中调用的钩子。钩子是全局的,不是按目标定义存储的。

8.1 plugin

使用这个方法可以指定在安装过程中应该使用的插件,以及在调用插件时应该传递给插件的选项。

示例:

plugin 'cocoapods-keys', :keyring => 'Eidolon'
plugin 'slather'

8.2 pre_install

这个钩子允许你对pod在下载完成之后,但是在install之前做一些操作。

示例:

pre_install do |installer|
  # Do something fancy!
end

8.3 pre_integrate

该钩子允许您在将项目写入磁盘之前进行更改。

示例:

pre_integrate do |installer|
  # perform some changes on dependencies
end

8.4 post_install

这个钩子允许你在生成的Xcode项目被写入磁盘之前对它做任何最后的修改,或者任何你想要执行的任务。

示例:

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

8.5 post_integrate

这个钩子允许您在项目被写入磁盘后进行更改。

示例:

post_integrate do |installer|
  # some change after project write to disk
end
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容