Swift Package Manager
可参考:
基本概念
参考:
模块Modules
在 Swift 中我们使用模块来管理代码,每个模块指定一个命名空间并强制指定模块外哪些部分的代码是可以被访问控制的。
一个程序可以将它所有代码聚合在一个模块中,也可以将它作为依赖关系导入到其他模块。除了少量系统提供的模块,像 OS X 中的 Darwin 或者 Linux 中的 Glibc 等的大多数依赖需要代码被下载或者内置才能被使用。
当你将编写的解决特定问题的代码独立成一个模块时,这段代码可以在其他情况下被重新利用。例如,一个模块提供了发起网络请求的功能,在一个照片分享的 app 或者 一个天气的 app 里它都是可以使用的。使用模块可以让你的代码建立在其他开发者的代码之上,而不是你自己去重复实现相同的功能。
包Packages
一个包由 Swift 源文件和一个清单文件组成。这个清单文件称为
Package.swift
,定义包名或者它的内容使用PackageDescription
模块。一个包有一个或者多个目标,每个目标指定一个产品并且可能声明一个或者多个依赖。
产品Products
一个目标可能构建一个库或者一个可执行文件作为其产品。库是包含可以被其他 Swift 代码导入的模块。可执行文件是一段可以被操作系统运行的程序。
依赖Dependencies
目标依赖是指包中代码必须添加的模块。依赖由包资源的绝对或者相对 URL 和一些可以被使用的包的版本要求所组成。包管理器的作用是通过自动为工程下载和编译所有依赖的过程中,减少协调的成本。这是一个递归的过程:依赖能有自己的依赖,其中每一个也可以具有依赖,形成了一个依赖相关图。包管理器下载和编译所需要满足整个依赖相关图的一切。
例子
内容来自An Introduction to Swift Package Manager
创建Package
可以参考官方文档Using the Package Manager
先创建一个文件夹
mkdir Website
cd Website
使用下面的命令,创建一个可执行工程
swift package init --type=executable
如果想创建library,可以忽略掉type参数,直接使用
swift package init
可以看到有如下的输出
Package.swift
文件内容如下:
import PackageDescription
let package = Package(
name: "Website",
dependencies: [
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
.target(
name: "Website",
dependencies: []),
.testTarget(
name: "WebsiteTests",
dependencies: ["Website"]),
]
)
每个package都有个name和一个target列表。
添加依赖
添加依赖,需要如下的信息:
- URL
- 版本号
- 名称 - 一般可以在
Package.swift
中找到
指定的依赖的时候,可以对version做控制,甚至对branch也可以
.package(url: "https://github.com/...git", from: "1.1.3")
指定了从1.1.3
开始且小于2.0.0
的任何版本的依赖
.package(url: "https://github.com/...git", "1.1.0"..."1.2.1")
指定范围,指定一个最大版本和最小版本
.package(url: "https://github.com/...git", .exact("1.2.3"))
指定确切的版本
.package(url: "https://github.com/...git", from: "1.1.3-beta.4")
支持beta版本
.package(url: "https://github.com/...git", .branch("bugfix/issue-121"))
也可以将dependency指定为某个分支
.package(url: "https://github.com/...git",
.revision("04136e97a73b826528dd077c3ebab07d9f8f48e2"))
通过hash指定一个commit
例子中的依赖是WebsiteBuilder,在manifest中指定如下:
.package(url: "https://github.com/raywenderlich/spm-tutorial.git", from: "1.0.0")
在target中添加package的名称
.target(
name: "Website",
dependencies: ["WebsiteBuilder"]),
与Xcode集成
swift package generate-xcodeproj
如上的命令,下载依赖,并创建Xcode工程 - Website.xcodeproj
如果你以前使用过Swift Package Manager,你可能会注意到我们并没有要求你使用
swift build
。 这是因为Xcode项目生成命令会为你执行此操作,并在构建项目之前解析依赖关系树。
然后就可以打开这个工程了,可以在终端通过如下的命令
open ./Website.xcodeproj
或者使用xed
,在当前的文件夹中打开工程
xed .
管理依赖
将依赖修改为如下:
.package(url: "https://github.com/raywenderlich/spm-tutorial.git", .exact("1.0.0"))
修改manifest后,依赖并不会自动更新,需要
swift package update
上面的命令,会自动选择不同或者最新的版本,然后下载
然后需要重新生成Xcode项目
swift package generate-xcodeproj
从终端运行
通常使用的是swift run
,这将构建你的应用程序并运行生成的可执行文件
如果有多个可执行目标,只需将目标名称添加到命令中:
swift run Website
另一个常见的任务是运行单元测试
swift test
不要运行
swift test
,因为它将在后台运行服务器并且永远不会停止它。 测试服务器端Swift项目不在本教程的讨论范围内,因此了解此命令很重要,但该项目并未设置用于测试。
使用以下命令构建可执行文件而不运行它
swift build
Build Configurations
上面的命令默认使用debug配置。 有更多可用的配置。 最常见的是release
swift run --configuration release
编辑Libaray
第一步是将package置于可编辑模式
swift package edit WebsiteBuilder
这会将WebsiteBuilder
移动到Dependencies
文件夹,SPM将不会更新和改变这个依赖。在编辑包之前,请重新生成Xcode项目