包管理器
Swift 包管理器 (SwiftPM) 是一款用于管理 Swift 代码分发的工具。它与 Swift 构建系统集成,可以自动化下载、编译和链接依赖项的过程。
包管理器包含在 Swift 3.0 及更高版本中。
概念概览
本节介绍 Swift 包管理器功能背后的基本概念。
模块
Swift 将代码组织成模块。每个模块指定一个命名空间,并对模块外部可以使用哪些代码部分强制执行访问控制。
一个程序可以将其所有代码放在一个模块中,或者它可以导入其他模块作为依赖项。除了少数系统提供的模块(例如 macOS 上的 Darwin 或 Linux 上的 Glibc)外,大多数依赖项都需要下载和构建代码才能使用。
当您为解决特定问题的代码使用单独的模块时,该代码可以在其他情况下重用。例如,一个提供网络请求功能的模块可以在照片共享应用程序和天气应用程序之间共享。使用模块可以让您在其他开发人员的代码之上构建,而不是自己重新实现相同的功能。
包
一个包由 Swift 源文件和一个清单文件组成。清单文件名为 Package.swift
,它使用 PackageDescription
模块定义包的名称及其内容。
一个包有一个或多个目标。每个目标指定一个产品,并且可以声明一个或多个依赖项。
产品
目标可以构建库或可执行文件作为其产品。库包含一个可以被其他 Swift 代码导入的模块。可执行文件是可以由操作系统运行的程序。
依赖项
目标的依赖项是包中代码所需的模块。依赖项由包源的相对或绝对 URL 以及一组可用于包版本的需求组成。包管理器的作用是通过自动化下载和构建项目所有依赖项的过程来降低协调成本。这是一个递归过程:依赖项可以有自己的依赖项,每个依赖项也可以有依赖项,从而形成依赖关系图。包管理器下载并构建满足整个依赖关系图所需的一切内容。
以下部分假设您已掌握 Swift 的工作知识。如果您是该语言的新手,您可能需要首先查阅入门资源之一。我们推荐The Swift Programming Language 中的 Swift 游览。
如果您想跟随代码示例进行操作,则需要安装可用的 Swift。您可以在入门中找到有关如何安装 Swift 的说明。
示例用法
在入门中,使用 Swift 包管理器构建了一个简单的命令行工具。
为了更完整地了解 Swift 包管理器的功能,以下示例包含三个相互依赖的包
- PlayingCard - 定义
PlayingCard
、Suit
和Rank
类型。 - DeckOfPlayingCards - 定义一个
Deck
类型,该类型可以洗牌和发牌一组PlayingCard
值。 - Dealer - 定义一个可执行文件,该文件创建一个
DeckOfPlayingCards
,对其进行洗牌,并发出前 10 张牌。
您可以通过从 GitHub 上的 Dealer 项目下载源代码并运行以下命令来构建和运行完整示例
$ git clone https://github.com/apple/example-package-dealer.git $ cd example-package-dealer $ swift run dealer <count>
创建库包
我们将从创建一个目标开始,该目标表示标准 52 张牌组中的一张扑克牌。PlayingCard
目标定义了 PlayingCard
类型,该类型由 Suit
枚举值(梅花、方块、红桃、黑桃)和 Rank
枚举值(A、2、3、...、J、Q、K)组成。
public enum Rank: Int {
case two = 2
case three, four, five, six, seven, eight, nine, ten
case jack, queen, king, ace
}
public enum Suit: String {
case spades, hearts, diamonds, clubs
}
public struct PlayingCard {
let rank: Rank
let suit: Suit
}
按照惯例,目标包括位于 Sources/<target-name>
目录中的任何源文件。
example-package-playingcard
├── Sources
│ └── PlayingCard
│ ├── PlayingCard.swift
│ ├── Rank.swift
│ └── Suit.swift
└── Package.swift
由于 PlayingCard
目标不生成可执行文件,因此可以将其描述为库。库是一个目标,它构建一个可以被其他包导入的模块。默认情况下,库模块公开位于 Sources/<target-name>
目录中的源代码中声明的所有 public
类型和方法。
当创建旨在用作其他项目依赖项的库包时,Package.swift
清单必须位于包目录结构的最顶层/根目录。
运行 swift build
以启动 Swift 构建过程。如果一切正常,它将为 PlayingCard
编译 Swift 模块。
PlayingCard
包的完整代码可以在 https://github.com/apple/example-package-playingcard 中找到。
导入依赖项
DeckOfPlayingCards
包引入了之前的包:它定义了 Deck
类型。
要使用 PlayingCards
模块,DeckOfPlayingCards
包必须在其 Package.swift
清单文件中将该包声明为依赖项。
// swift-tools-version:5.3
import PackageDescription
let package = Package(
name: "DeckOfPlayingCards",
products: [
.library(name: "DeckOfPlayingCards", targets: ["DeckOfPlayingCards"]),
],
dependencies: [
.package(url: "https://github.com/apple/example-package-playingcard.git", from: "3.0.0"),
],
targets: [
.target(
name: "DeckOfPlayingCards",
dependencies: ["PlayingCard"]),
.testTarget(
name: "DeckOfPlayingCardsTests",
dependencies: ["DeckOfPlayingCards"]),
]
)
每个依赖项都指定一个源 URL 和版本要求。源 URL 是当前用户可以访问的 URL,该 URL 解析为 Git 存储库。版本要求遵循 语义版本控制 (SemVer) 约定,用于确定要检出和用于构建依赖项的 Git 标签。对于 PlayingCard
依赖项,将使用主版本等于 3
的最新版本。
当运行 swift build
命令时,包管理器会下载所有依赖项,编译它们,并将它们链接到包模块。这允许 DeckOfPlayingCards
通过 import
语句访问其依赖模块的公共成员。
您可以在项目根目录的 .build/checkouts
目录中查看下载的源文件,并在项目根目录的 .build
目录中查看中间构建产品。
DeckOfPlayingCards
包的完整代码可以在 https://github.com/apple/example-package-deckofplayingcards 中找到。
解决传递依赖项
在完成所有其他步骤后,您现在可以构建 Dealer
模块。Dealer
模块依赖于 DeckOfPlayingCards
包,而后者又依赖于 PlayingCard
包。但是,由于 Swift 包管理器会自动解析传递依赖项,因此您只需将 DeckOfPlayingCards
包声明为依赖项即可。
// swift-tools-version:5.5
import PackageDescription
let package = Package(
name: "dealer",
products: [
.executable(name: "Dealer", targets: ["Dealer"]),
],
dependencies: [
.package(url: "https://github.com/apple/example-package-deckofplayingcards.git", from: "3.0.0"),
],
targets: [
.target(
name: "Dealer",
dependencies: ["DeckOfPlayingCards"]),
]
)
Swift 要求源文件导入代码中引用的任何类型的模块。对于 Dealer
模块的 main.swift
文件,引用了 DeckOfPlayingCards
中的 Deck
类型和 PlayingCard
中的 PlayingCard
类型。
import DeckOfPlayingCards
let numberOfCards = 10
var deck = Deck.standard52CardDeck()
deck.shuffle()
for _ in 1...numberOfCards {
guard let card = deck.deal() else {
print("No More Cards!")
break
}
print(card)
}
按照惯例,目录中包含名为 main.swift
的文件的目标会生成可执行文件。
运行 swift build
命令会启动 Swift 构建系统以生成 Dealer
可执行文件,该文件可以从 .build/debug
目录运行。
$ swift build
$ ./.build/debug/Dealer
♠︎6
♢K
♢2
♡8
♠︎7
♣︎10
♣︎5
♢A
♡Q
♡7
Dealer
包的完整代码可以在 https://github.com/apple/example-package-dealer 中找到。
有关使用 Swift 包管理器的更多信息,请参阅 GitHub 上的 Swift Package Manager 项目中提供的文档。