当前位置:   article > 正文

CocoaPods使用指南

cocoapods使用

CocoaPods使用指南 作者

前言

对于大多数软件开发团队来说,依赖管理工具必不可少,它能针对开源和私有依赖进行安装与管理,从而提升开发效率,降低维护成本。针对不同的语言与平台,其依赖管理工具也各有不同,例如 npm 管理 Javascript、Gradle 、Maven 管理 Jar 包、pip 管理 Python 包,Bundler、RubyGems 等等。本文聚焦于 iOS 方面,对 CocoaPods 的使用和部分原理进行阐述。

简单易用的 CocoaPods

对于 iOSer 来说,CocoaPods 并不陌生,几乎所有的 iOS 工程都会有它的身影。CocoaPods 采用 Ruby 构建,它是 Swift 和 Objective-C Cocoa 项目的依赖管理工具。在 MacOS 上,推荐使用默认的 Ruby 进行安装 (以下操作均在 CocoaPods 1.10.1、Ruby 2.7.2 进行):

sudo gem install cocoapods
  • 1

如果安装成功,便可以使用 pod 的相关命令了。针对一个简单的项目来说,只需三步便可引入其他的依赖:

创建 Podfile 文件( CocoaPods 提供了 pod init 命令创建)
对 Podfile 文件进行编写,添加依赖的库,版本等信息。
在命令行执行 pod install 命令

顺利的话,这时在项目目录下会出现以下文件:

  • .xcworkspace:CocoaPods 将项目分为了主工程与依赖工程(Pods)。与 .xcodeproj 相比 .xcworkspace 对于管理多个项目的能力更强,你也可以将复杂的大型应用转换为以 .xcworkspace 构建的多个兄弟项目,从而更轻松的维护和共享功能。
  • Podfile.lock:记录并跟踪依赖库版本,将依赖库锁定于某个版本。
  • Pods 文件夹:存放依赖库代码。
  • Pods/Manifest.lock:每次 pod install 时创建的 Podfile.lock 的副本,用于比较这两个文件。一般来说,Podfile.lock 会纳入版本控制管理,而 Pods 文件夹则不会纳入版本控制变更;这意味着 Podfile.lock 表示项目应该依赖的库版本信息,而 Manifest.lock 则代表本地 Pods 的依赖库版本信息。在 pod install 后会将脚本插入到 Build Phases,名为 [CP] Check Pods Manifest.lock,从而保证开发者在运行 app 之前能够更新 Pods,以确保代码是最新的。

pod install vs. pod update

  • pod install:在每一次编辑 Podfile 以添加、更新或删除 pod 时使用。它会下载并安装新的 Pod,并将其版本信息写入 Podfile.lock 中。
  • pod outdated:列出所有比 Podfile.lock 中当前记录的版本 newer 版本的 pod。
  • pod update [PODNAME]:CocoaPods 会查找 newer 版本的 PODNAME,同时将 pod 更新到可能的最新版本(须符合 Podfile 限制)。若没有 PODNAME,则会将每一个 pod 更新到可能的最新版本。

一般来说,每次编辑 Podfile 时使用 pod install,仅在需要更新某个 pod 版本(所有版本)时才使用 pod update。同时,需提交 Podfile.lock 文件而不是 Pods 文件夹来达到同步所有 pod 版本的目的。

ps: newer 代表更加新的,若采用中文理解起来比较别扭。

Podfile 语法规范

Podfile 描述了一个或多个 Xcode 项目的 target 依赖关系,它是一种 DSL,了解它对我们使用好 CocoaPods 是一个必不可少的步骤。下面列出其相关的语法规范:

Root Options

install!:指定 CocoaPods 安装 Podfile 时使用的安装方法和选项。如:

install! 'cocoapods',
         :deterministic_uuids => false,
         :integrate_targets => false
  • 1
  • 2
  • 3
  • :clean:根据 podspec 和项目支持平台的指定,清理所有不被 pod 使用的文件,默认为 true。
  • :deduplicate_targets:是否对 pod target 进行重复数据删除,默认为 true。
  • :deterministic_uuids:创建 pod project 是否产生确定性 UUID,默认为 true。
  • :integrate_targets:是否继承到用户项目中,为 false 会将 Pod 下载并安装到到 project_path/Pods 目录下,默认为 true。
  • :lock_pos_sources:是否锁定 pod 的源文件,当 Xcode 尝试修改时会提示解锁文件,默认为 true。
  • :warn_for_multiple_pod_sources:当多个 source 包含同名同版本 pod 时是否发出警告,默认为 true。
  • :warn_for_unused_master_specs_repo:如果没有明确指出 master specs repo 的 git 是否发出警告,默认为 true。
  • :share_schemes_for_development_pods:是否为开发中的 pod 分享 schemes,默认为 false。
  • :disable_input_output_paths:是否禁用 CocoaPods 脚本阶段的输入输出路径(Copy Frameworks 和 Copy Resources),默认为 false。
  • :preserve_pod_file_structure:是否保留所有 pod 的文件结构,默认为 false。
  • :generate_multiple_pod_projects:是否为每一个 pod target 生成 一个 project,生成与 Pods/Pods 文件夹中,默认为 false。
  • :incremental_installation:仅对自上次安装的 target 与其关联的 project 的变更部分进行重新生成,默认为 false。
  • :skip_pods_project_generation:是否跳过生成 Pods.xcodeproj 并仅进行依赖项解析与下载,默认为 false。 ensure_bundler!:当 bundler 版本不匹配时发出警告。
ensure_bundler! '~> 2.0.0'
  • 1

Dependencies

pod:指定项目的依赖项

  • 依赖版本控制:=、>、>=、<、<= 为字面意思;~> 0.1.2 表示 0.1.2 <= currVersion < 0.2 之间的符合要求的最新版本版本。
  • Build configurations:默认依赖安装在所有的构建配置中,但也可仅在指定构建配置中启用。
  • Modular Headers:用于将 pod 转换为 module 以支持模块,这时在 Swift 中可以不用借助 bridging-header 桥接就可以直接导入,简化了 Swift 引用 Objective-C 的方式;也可以采用 use_modular_headers! 进行全局的变更。
  • Source:指定具有依赖项的源,同时会忽略全局源。
  • Subspecs:默认会安装所有的 subspecs,但可制定安装某些 subspecs。
  • Test Specs:默认不会安装 test specs,但可选择性安装 test specs。
  • Local path:将开发的 pod 与其客户端一起使用,可采用 path。
  • 指定某个特殊或者更为先进的 pod 版本
# 依赖版本控制
pod 'Objection', '~> 0.9' 
# Build configurations
pod 'PonyDebugger', :configurations => ['Debug', 'Beta'] 
# Modular Headers
pod 'SSZipArchive', :modular_headers => true 
# Source
pod 'PonyDebugger', :source => 'https://github.com/CocoaPods/Specs.git'
# Subspecs
pod 'QueryKit', :subspecs => ['Attribute', 'QuerySet'] 
# Test Specs
pod 'AFNetworking', :testspecs => ['UnitTests', 'SomeOtherTests']
# Local path
pod 'AFNetworking', :path => '~/Documents/AFNetworking'
# 指定某个特殊或者更为先进的 Pod 版本
pod 'AFNetworking', :git => 'https://github.com/gowalla/AFNetworking.git', :branch => 'dev'
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
pod 'JSONKit', :podspec => 'https://example.com/JSONKit.podspec'
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

inherit:设置当前 target 的继承模式。

  • :complete 继承父级 target 的所有行为,:none 不继承父级 target 的任何行为,:search_paths 仅继承父级的搜索路径。
target 'App' do
  target 'AppTests' do
    inherit! :search_paths
  end
end
  • 1
  • 2
  • 3
  • 4
  • 5

target:与 Xcode 中的 target 相对应,block 中是 target 的依赖项。
默认情况下,target 包含在父级 target 定义的依赖项,也即 inherit!:complete。关于 :complete:search_paths:complete 会拷贝父级 target 的 pod 副本,而 :search_paths 则只进行 FRAMEWORK_SEARCH_PATHSHEADER_SEARCH_PATHS 的相关拷贝,具体可通过比对 Pods/Target Support Files 的相关文件得以验证,一般在 UnitTests 中使用,以减少多余的 install_framework 过程。

target 'ShowsApp' do
  pod 'ShowsKit'
  # 拥有 ShowsKit 和 ShowTVAuth 的拷贝
  target 'ShowsTV' do
    pod 'ShowTVAuth'
  end
  # 拥有 Specta 和 Expecta 的拷贝
  # 并且能够通过 ShowsApp 进行访问 ShowsKit, 相当于 ShowsApp 是 ShowsTests 的宿主APP
  target 'ShowsTests' do
    inherit! :search_paths
    pod 'Specta'
    pod 'Expecta'
  end
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

abstract_target:定义 abstract_target,方便 target 进行依赖继承,在 CocoaPods 1.0 版本之前为 link_with

abstract_target 'Networking' do
  pod 'AlamoFire'
  target 'Networking App 1'
  target 'Networking App 2'
end
  • 1
  • 2
  • 3
  • 4
  • 5

abstract:表示当前 target 是抽象的,不会链接到 Xcode 的 target 中。
script_phase:添加脚本阶段。
在执行完 pod install 之后 CocoaPods 会将脚本添加到对应的 target build phases。

target 'App' do
script_phase {
:name => 'scriptName' # 脚本名称,
        :script => 'echo "nihao"' # 脚本内容,
        :execution_position => :before_compile / :after_compile
        :shell_path => '/usr/bin/ruby' # 脚本路径
        :input_files => ['/input/filePath'], # 输入文件
        :output_files => ['/outpput/filePath'] # 输出文件
}
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

Target configuration

platform:指定其构建平台。
默认值为 iOS 4.3、OSX 10.6、tvOS 9.0 和 watchOS 2.0。CocoaPods 1.0 之前的版本为 xcodeproj

platform :ios, '4.0'
  • 1

project:指定包含 target 的 Xcode project。这一般在 workspace 存在多个 xcode project 中使用:

# 在 FastGPS Project 中可以找到一个名为 MyGPSApp 的 target
target 'MyGPSApp' do
  project 'FastGPS'
  ...
end
  • 1
  • 2
  • 3
  • 4
  • 5

inhibit_all_warnings!:禁止所有警告。如果针对单个 Pod,则可以采用:

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

user_modular_headers!:将所有 Pod 模块化。如果针对单个 Pod,则可以采用:

pod 'SSZipArchive', :modular_headers => true
pod 'SSZipArchive', :modular_headers => false
  • 1
  • 2

user_frameworks!:采用 framework 而不是 .a 文件的静态库。
可以通过 :linkage 指定使用静态库还是动态库:

use_frameworks!:linkage => :dynamic / :static
  • 1

supports_swift_versions:指定 target definition 支持的 swift 版本要求

 supports_swift_versions '>= 3.0', '< 4.0' 
  • 1

Workspace

workspace:指定包含所有项目的 Xcode workspace。

workspace 'MyWorkspace'
  • 1

Sources

sources:Podfile 从指定的源列表中进行检索。sources 默认存储在 ~/.cocoapods/repos 中,是全局的而非按 target definition 存储。当有多个相同的 Pod 时,优先采用检索到的 Pod 的第一个源,因此当指定另一个来源时,则需显示指定 CocoaPods 的源。

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

Hooks

plugin:指定在安装期间使用的插件。

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

pre_install:在下载后和在安装 Pod 前进行更改。

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

pre_integrate:在 project 写入磁盘前进行更改。

pre_integrate do |installer|
  # perform some changes on dependencies
end
  • 1
  • 2
  • 3

post_install:对生成 project 写入磁盘前进行最后的修改。

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

post_integrate:在 project 写入磁盘后进行最后更改。

post_integrate do |installer|
  # some change after project write to disk
end
  • 1
  • 2
  • 3

podspec 语法规范

podspec = pod Specification,意为 pod 规范,它是一个 Ruby 文件。包含了 Pod 的库版本详细信息,例如应从何处获取源、使用哪些文件、要应用构建设置等信息;也可以看作该文件是整个仓库的索引文件,了解它对我们知道 Pod 库是如何组织、运作的提供了很大帮助。podspec 的 DSL 提供了极大的灵活性,文件可通过 pod spec create 创建。

Root

名称用途必需
namepod 名称required
versionpod 版本,遵循语义化版本控制required
swift_version支持的 Swift 版本
cocoapods_version支持的 CocoaPods 版本
authorspod 维护者的姓名和电子邮件,用“, ”进行分割required
licensepod 的许可证required
homepagepod 主页的 URLrequired
source源地址,即源文件的存放地址,支持多种形式源required
summarypod 的简短描述required
prepare_command下载 pod 后执行的 bash 脚本
static_framework是否采用静态 framework 分发
deprecated该库是否已被弃用
deprecated_in_favor_of该库名称已被弃用,取而代之
Pod::Spec.new do |s|
  s.name             = 'CustomPod'
  s.version          = '0.1.0'
  s.summary          = 'A short description of CustomPod.'
  s.swift_versions   = ['3.0', '4.0', '4.2']
  s.cocoapods_version  =  '>= 0.36'
  s.author           = { 'nihao' => 'XXXX@qq.com' }
  s.license          = { :type => 'MIT', :file => 'LICENSE' }
  s.homepage         = 'https://github.com/XXX/CustomPod'

# Supported Key
# :git=> :tag, :branch, :commit,:submodules
# :svn=> :folder, :tag,:revision
# :hg=>:revision
# :http=> :flatten, :type, :sha256, :sha1,:headers
  s.source           = { :git => 'https://github.com/XX/CustomPod.git', :tag => s.version.to_s }
  s.prepare_command  =  'ruby build_files.rb'
  s.static_framework = true
  s.deprecated       = true
  s.deprecated_in_favor_of  =  'NewMoreAwesomePod'
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

Platform

platform:pod 支持的平台,留空意味着 pod 支持所有平台。当支持多平台时应该用 deployment_target 代替。

spec.platform = :osx, '10.8'
  • 1

deployment_target:允许指定支持此 pod 的多个平台,为每个平台指定不同的部署目标。

spec.ios.deployment_target = '6.0'
spec.osx.deployment_target = '10.8'
  • 1
  • 2

Build settings

dependency:基于其他 pods 或子规范的依赖

spec.dependency 'AFNetworking', '~&gt; 1.0', :configurations =&gt; ['Debug']
  • 1

info_plist:加入到生成的 Info.plist 的键值对,会对 CocoaPods 生成的默认值进行覆盖。仅对使用 framework 的框架有影响,对静态库无效。对于应用规范,这些值将合并到应用程序主机的 Info.plist;对于测试规范,这些值将合并到测试包的 Info.plist。

spec.info_plist = {
  'CFBundleIdentifier' =&gt; 'com.myorg.MyLib',
  'MY_VAR' =&gt; 'SOME_VALUE'
}
  • 1
  • 2
  • 3
  • 4

requires_arc:允许指定哪些 source_files 采用 ARC,不使用 ARC 的文件将具有 -fno-objc-arc 编译器标志

spec.requires_arc = false
spec.requires_arc = 'Classes/Arc'
spec.requires_arc = ['Classes/*ARC.m', 'Classes/ARC.mm']
  • 1
  • 2
  • 3

frameworks:使用者 target 需要链接的系统框架列表

spec.ios.framework = 'CFNetwork'
spec.frameworks = 'QuartzCore', 'CoreData'
  • 1
  • 2

weak_frameworks:使用者 target 需要弱链接的框架列表

spec.weak_framework = 'Twitter'
spec.weak_frameworks = 'Twitter', 'SafariServices'
  • 1
  • 2

libraries:使用者 target 需要链接的系统库列表

spec.ios.library = 'xml2'
spec.libraries = 'xml2', 'z'
  • 1
  • 2

compiler_flags:应传递给编译器的 flags

spec.compiler_flags = '-DOS_OBJECT_USE_OBJC=0', '-Wno-format'
  • 1

pod_target_xcconfig:将指定 flag 添加到最终 pod 的 xcconfig 文件

spec.pod_target_xcconfig = { 'OTHER_LDFLAGS' =&gt; '-lObjC' }
  • 1

user_target_xcconfig

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/1004306
推荐阅读
相关标签