CocoaPods 1.4.0 — 功能齐全!

CocoaPods 1.4.0 随附了许多新功能,例如测试的应用主机支持、脚本阶段、静态框架支持以及新的 Swift 版本 DSL!

在 CocoaPods 1.3.0 发布几个月后,我们公布了一个新版本,增加了许多强大的新功能。让我们直接进入正题!

测试规范的应用主机支持

CocoaPods 1.3.0 引入了对测试规范的支持,但最初,吊舱作者无法使用需要应用主机的测试规范。使用 1.4.0,您现在可以指定需要应用主机才能执行测试。

您可以通过在测试规范中设置 requires_app_host 属性来实现此目的

s.test_spec 'Tests' do |test_spec|
  test_spec.requires_app_host = true
  test_spec.source_files = 'Tests/**/*.{h,m,swift}'
end

启用后,CocoaPods 将自动创建一个存根应用主机并将其与您的测试包目标链接。这使您能够描述使用 UIKit 才能运行的测试源。CocoaPods 将在项目中集成的所有测试规范中重复使用同一应用主机。对于 iOS,CocoaPods 生成的应用主机将创建并添加一个空视图控制器。

注意:应用主机支持目前不适用于 watchOS 平台。

自 1.3.0 中首次推出测试规范以来,我们还进行了一些修复,因此我们强烈建议您升级并开始使用测试规范!

脚本阶段

脚本阶段集成是 CocoaPods 1.4.0 一项期待已久且强大的新功能。吊舱作者和应用开发者现在可以使用 CocoaPods 在其 podfile 或 podspec 中集成脚本阶段。

Podfile

对于应用开发者,每个目标现在允许您指定一个 script_phase 属性,该属性将自动将脚本阶段集成到您的目标中。以下是一个示例

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

install! 'cocoapods'

platform :ios, '9.0'

target 'SampleApp' do
  pod 'Alamofire'
  script_phase :name => 'Hello World', :script => 'echo "Hello World"'
end

这将产生以下结果

这允许你在 podfile 中表示应用目标的脚本阶段,而无需在 .xcodeproj 中维护它们。每个脚本阶段都以 [CP-User] 为前缀,因此你可以轻松地将其作为自己的脚本阶段加以区分,并且知道它已由 CocoaPods 自动添加。你可以为每个目标设置多个脚本阶段,并且你指定它们的顺序就是它们添加到你的目标中的顺序。

Podspec

通常情况下,库可能希望在编译期间执行一些任务。到目前为止,pod 作者只能通过 prepare_command 属性执行配置任务,但是,这仅在你首次安装或更新 pod 时执行。此外,在执行 prepare_command 期间,不会设置任何 Xcode 环境变量,因为它们是在构建执行期间设置的。

使用 CocoaPods 1.4.0,你现在可以在 podspec 中指定一个 script_phase 属性,该属性在 pod 的构建过程中执行,使你可以完全访问 Xcode 构建环境。让我们使用我们最喜欢的示例 pod“CannonPodder”来看一个示例

Pod::Spec.new do |s|
  s.name         = 'CannonPodder'
  s.version      = '1.0.0'
  s.summary      = 'CannonPodder for the win.'
  s.homepage     = 'http://cannonpodder-corp.local/cannonpodder-lib.html'
  s.description  = 'All the Cannons'
  s.source       = { :git => 'http://somewhere.com/cannonpodder.git', :tag => '1.0.0' }
  s.license      = { :type => 'MIT', :text => 'Permission is hereby granted ...' }

  s.ios.deployment_target = '9.0'
  s.osx.deployment_target = '10.10'

  s.script_phase = { :name => 'Hello World', :script => 'echo "Hello World"' }

  s.source_files = 'Sources/**/*.{h,m,swift}'

  s.private_header_files = 'Sources/Internal/**/*.h'
end

上述内容将自动向 CocoaPods 生成的 CannonPodder-iOSCannonPodder-macOS 目标添加一个脚本阶段。它看起来像这样

如果你的 pod 支持多个平台,你可以将脚本阶段仅限制到特定平台,例如

s.ios.script_phase = { :name => 'Hello iOS World', :script => 'echo "Hello iOS World"' }

上述示例只会向 CannonPodder-iOS 目标添加一个脚本阶段。

此外,有时你希望在编译之前执行脚本阶段以执行配置步骤,例如生成一些源或执行 lint 检查。CocoaPods 1.4.0 通过每个 script_phase 条目中的 :execution_position 属性提供对它的支持。

例如

s.script_phase = {
  :name => 'Hello World',
  :script => 'echo "Hello World"',
  :execution_position => :before_compile
}

生成以下内容

CocoaPods 将在 编译源 阶段之前自动添加脚本阶段。这实际上允许你控制希望在哪个阶段执行脚本阶段,并允许你根据编译阶段执行不同类型的任务。

下面是一个稍微复杂一些的示例,演示了在不同阶段运行的两个脚本阶段

s.script_phases = [
  { :name => 'Precompile',
    :script => '${PODS_TARGET_SRCROOT}/setup.sh',
    :execution_position => :before_compile
  },
  { :name => 'Postcompile',
    :script => 'echo "yay!"',
    :execution_position => :after_compile
  }
]

目前,可用的执行位置有 :before_compile:after_compile:any,后者是默认值,由 CocoaPods 内部保留。当你使用 :any 时,它的行为目前与 :after_compile 相同,但将来可能会更改。这就是为什么在 podspec 中定义 script_phase 时始终建议指定 execution_position 属性的原因。

将来,我们希望扩展 :execution_phase 属性并提供更精细的选项,以便您指定脚本阶段应该在哪个时间点执行。

注意:如果您希望脚本阶段在执行期间访问 pod 的任何源,那么强烈建议使用 ${PODS_TARGET_SRCROOT} 环境变量,该变量针对每个 pod 设置,并且始终相对于 pod 源的路径。

安全警告

虽然脚本阶段是 CocoaPods 的一项强大功能,但了解到包含脚本阶段的 pod 可能会对许多人构成很高的安全漏洞至关重要。毕竟,此功能本质上允许 pod 作者在您决定将他们的 pod 集成到您的项目中时在您的机器上执行代码。

出于此原因,当您安装 pod 或将 pod 更新到添加脚本阶段作为其构建过程一部分的新版本时,CocoaPods 始终会显示警告。

警告将按如下方式显示(单击以放大)

注意:此警告无法禁用,并且会在您首次安装 pod 或现有 pod 更新并包含脚本阶段时出现。必须检查脚本阶段的内容以确保在编译过程中不会执行任何有害代码。

在未来版本中,CocoaPods 将在为 pod 执行 prepare_command 之前提示您,以便您检查其内容。

静态框架

源静态框架是 CocoaPods 1.4.0 的另一项强大新功能。首次可以分发源并将其构建到静态框架中,当在 Podfile 中指定 use_frameworks! 时。由于动态库不能依赖于静态库,因此现在可以分发依赖于其他静态库框架的 pod,包括当今作为 vendored_frameworks 发布的许多静态框架。

背景

框架是库、头文件和资源的集合。该库可以是动态的或静态的。静态库在构建时链接,而动态库在运行时链接和加载。

动态库无法依赖静态库,因为静态库可能没有在运行时加载所需的重定位,并且如果多个动态库依赖于同一静态库,则会有多个静态库副本。多个副本仅是代码本身的代码大小问题,但它会导致静态库中任何数据的功能问题。

当 Apple 和 Xcode 引用框架时,通常暗示动态。但是,较低级别的 Apple 构建工具可以正确处理动态和静态框架。

历史上,许多二进制 CocoaPods 已作为包含静态库的 vendored_framework 分发。

在 1.4.0 之前,源只能构建为动态框架。因此,无法依赖许多 vendored_framework CocoaPods。此外,以二进制形式交付其 pod 的供应商无法将其转换为源 CocoaPod 并将其保留为静态框架。

用法

要启用静态框架支持,请将以下内容添加到您的 podspec

s.static_framework = true

瞧!

Swift 版本 DSL

使用 CocoaPods 1.4.0,您现在可以通过 swift_version 属性在您的 podspec 中指定您的 pod 正式支持的 Swift 版本。自 Xcode 9 发布以来,现在允许每个目标使用多个 Swift 版本。CocoaPods 始终默认为您的应用程序目标正在使用的 Swift 版本。随着 Swift 的发展,当前集成不再可持续。例如,将您的项目升级到 Swift 4.0 并不一定意味着您使用的所有 Swift pod 也能使用 Swift 4.0 成功编译,因此您必须等到新版本的 pod 发布才能升级到最新版本的 Swift 或使用 post_install 钩子手动编辑配置。

作为 pod 作者,您现在可以将以下内容添加到您的 podspec

s.swift_version = '4.0'

这将在使用 pod 时自动为其配置 Swift 4.0,而不管应用程序目标使用的 Swift 版本如何。作为作者,您应该始终测试并提供已知版本的 Swift,该版本可以与您的 pod 顺利配合,并相应更新您的 podspec。

注意:现在已弃用 .swift-version 文件以及 lint 期间的 --swift-version 参数。您可以继续使用它,但您会收到警告,建议您改用 swift_version 属性。

我们旨在通过允许 pod 作者指定其 pod 支持的 Swift 版本范围(而不是单个 Swift 版本)来改进对该功能的支持,但对于大多数人来说,这已经足够了。我们希望与 Apple 的 Swift 路线图保持分离,并且不必随着新版本的 Swift 和 Xcode 的推出而发布 CocoaPods。

过渡到 https

在此版本中,使用未加密的http源发布 Pod 已弃用,强烈建议开始使用https源托管 Pod。如果您尝试在未使用https源的主存储库中发布 Pod,将出现警告。在未来版本中,这将变得更加严格,您将无法在没有https源的情况下发布 Pod。

此外,在安装过程中,使用未加密的http源的 Pod 消费者也将收到警告,通知他们托管 Pod 的源可能不安全。

开发 Pod 文件

当您在本地 Pod 上进行开发(使用:path指令)时,通常非常有用,让其所有关联文件(例如文档文件、Pod 规范和许可证文件)易于获取和查看,以便您可以查看和编辑它们。在 1.4.0 中,所有这些文件现在都自动添加到生成的.xcodeproj中!以下文件将自动添加到工作区

  • Podspec
  • 文档(在与 glob 模式doc{s}{*,.*}匹配的文件夹中)
  • 自定义模块映射(使用 Pod 规范的module_map属性)
  • 前缀头文件(使用 Pod 规范的prefix_header_file属性)
  • 许可证(使用 Pod 规范的许可证属性,或使用 glob 模式licen{c,s}e{*,.*}自动找到)
  • 自述文件(与 glob 模式readme{*,.*}匹配)

这应该可以提升您在本地使用 Pod 时的开发体验。

摘要

CocoaPods 1.4.0 是一个重大的版本,它推动了 iOS 开发并引入了许多强大的功能。我们非常高兴您能试用它,并强烈建议您升级!

特别感谢所有为 CocoaPods 1.4.0 做出贡献的人,没有你们,我们无法做到这一点。

查看变更日志以获取完整更改列表。

<3