大多数浏览器和
Developer App 均支持流媒体播放。
-
了解 Swift Package Manager
通过 Swift Package Manager,您可以轻松地在 Swift 生态系统中开发和分发源代码。了解它的目标、设计、独特功能和持续改进机会。
资源
相关视频
WWDC19
-
下载
欢迎来到 Getting to Know Swift Manager 我是 Rick Ballard 和我一起的是 Boris Buegling 我们非常高兴 能来给你们介绍 Swift 的包管理器 有时也叫 SwiftPM 今天我们主要关注的 就是这个开源项目 而不是 Apple 的 其他开发者工具 今天要讲的内容有很多
Swift 包管理器 使得在 Swift 生态系统里 开发和分配源代码变得更轻松 今天我们就来讨论一下 它的目标 设计 还有一些对未来的展望
首先 我想先说一下 为什么我们决定 为 Swift 项目 创建一个新的包管理器 我们将简单介绍它的使用方法 然后深入讨论它的设计 和特性
我们还会讲到 我们未来的打算 最后会介绍 SwiftPM 的开源过程 以及如果你感兴趣 要如何加入
我相信你们大多数人对 包管理器都很熟悉 它们可以很好的用来 分享和再利用代码 但是我们为什么 要给 Swift 再做一个新的呢
首先是因为 Swift 是一个跨平台语言 所以我们想 为你的 Swift 代码 建一个跨平台工具 这样你可以更容易的 以一致的方式配置代码 并且在所有 Swift 支持的平台上使用 SwiftPM 包括 完整的构建系统 让你只用一个工具 就可以配置 构建 测试 甚至运行软件
同时 我们还致力于 让你能够将 你的 Swift 库 轻松分享给任何人 通过在 Swift 项目中 提供规范的包管理器 我们希望能 为分发库的方式 建立一个公共标准 这也有助于 Swift 生态系统的发展 让 Swift 变得更好 很多人可能有 想要添加的特性 但是我们对 加入核心库的内容非常谨慎 这样才能保证 我们的 API 是精心呈现的
优秀的包管理器 可以较为容易的以包的形式配置 想要添加的内容 而不是 直接把它们放入核心库 随着时间发展 优质的内容 在社区会越来越受欢迎 并且逐渐标准化
最后 建立 Swift 的包管理器 让我们可以利用 Swift 的功能和理念
SwiftPM 本身是 写在 Swift 里的 并且也是一个 Swift 包 除此之外 我们和 Swift 语言 以及核心库项目 通力合作 为包管理器构建了很棒的功能 能帮助你的 Swift 代码更好的发挥作用
SwiftPM 是 Swift 开源项目的一部分 在 Swift.org 和 GitHub 上都可以访问 Swift.org 上的 Swift 包管理器部分 是对其入门的好地方
如果你决定试着使用 你可以在所有 Swift 工具链中找到它 也可以从 Swift.org 下载 当然 它也和 Swift 工具一起 包含在 Xcode 的 每一次发布中
接下来讲解 如何使用 SwiftPM 让我们邀请 Boris Buegling 上台 展示一下基本内容
谢谢 Rick 让我们了解一下如何使用 SwiftPM
SwiftPM 包含四个 命令行工具 顶层是 Swift Command Swift Build 用于创建你的包 Swift Run 用于运行可执行文件 Swift Test 用于进行测试 Swift Package 用于对包进行 各种非创建操作 包储存在 git 储存区 并且用 git 标签 标示分支
接下来 我会演示 创建第一个 Swift 包 是多么简单的事情
从终端开始 创建一个新的目录叫 helloworld 这也是我们包的名字 转到该目录 并运行 swift package init --type executable 这样 SwiftPM 就创建了 一个基本包和结构
让我们打开访达 仔细看一下这个包
这个是 Package.swift 清单文件 用来描述包的结构 有一个 README 还有 Sources 目录
其中的子文件夹就是 我们的目标 helloworld 以及可执行项的 main.swift 文件 同时还有一个 test 目录 一会儿可以放入一些单元测试 让我们回到终端 输入 swift run 来构建和运行这个包 这个命令会编译该包 链接可执行项 于是我们看到了输出的 Hello,World! 下面 我要换另外一个终端窗口 在那里我准备了一个 复杂一点儿的包 在接下来讲解关于 SwiftPM 的基本概念时 我们会使用它 首先 让我们先运行一下 看看它是干嘛的 你可以看到 它会在终端随机产生 扑克牌花色和数字
现在 我们可以回到 幻灯片来说一说 SwiftPM 的基本概念
一个包分为三个 主要部分 依赖
目标和产品 接下来我们会 分别了解一下每一个部分
依赖是当你 开发功能的时候 可使用的 Swift 包 每个依赖提供 一个或多个产品 比如你的包可使用的库 让我们来看一下 包中的依赖 在 Swift 清单文件里是什么样子 每个依赖都有源位置 而且有版本号
目标是包的 基本构建模块
一个目标描述 如何将一组源文件 构建到模块或者测试套件中
目标可以依赖 同个包里的其他目标
或者从其他包里 导出的 声明为依赖的产品
产品可以由库 执行 产品是由一个或者多个目标的 构件组成的
包通过定义产品 为其他包提供库 默认情况下 你不需要声明库的类型 SwiftPM 会根据 它的使用情况来帮你选择
如果需要 你可以特定声明一个库 是静态的或者动态的 让我们看一下 目标是如何 清单中配置的 在这个例子里 一共有三个目标
第一个叫 libdealer 它包含了我们主要功能的执行 它有一个依赖 是 DeckOfPlayingCards 就是我们之前声明的 依赖的产品
第二个目标是 dealer 它需要依靠 前一个目标来提供 我们刚才运行的命令行工具 最后 有一个测试目标 它依赖于 其他两个目标 我们可以对功能进行单元测试
在我们的样例包中 我们还配置了两个产品
第一个是库产品 对应目标 libdealer
它把我们的执行结果 作为库提供给 外部使用 第二个是一个 可执行目标 它依靠 dealer 目标 为命令行提供可执行项
最后我要展示一下 如果运用包 为本例添加一个新功能
让我们换到一个新的 终端窗口然后打开 package.swift 清单文件 添加一个新依赖 这次 我们添加的是 SwiftPM 本身 正如 Rick 所说 它自己就是 Swift 包 但是它并不提供一个稳定的API 这就是为什么我们 要依赖于一个具体的版本号
我们还希望能 在 libdealer 目标中 依赖于一个 SwiftPM 的产品 叫做 Utility 它有一个类 叫做终端控制器 让我们可以 在终端中输出不同的颜色 请记住 这不是官方 Apple API 我们只是用来演示 让我们回到终端
在演示前 我已经更改了代码 来使用这个新依赖 让我们试着运行 看下结果 正如你所见 输出是一样的 但添加了一些颜色 变得更有趣了
现在我想展示最后一个演示
就是 SwiftPM 怎么运行测试 我们要使用 Swift Neo 包 它是一个 Apple 在春天发布的开源网络库 我们使用 --parallel 选项 运行 Swift Test
这让我们可以 进行平行测试 这样就可以更快的得到测试结果 还可以选择 filter 选项
这样你就可以运行子测试 基于单一结果进行迭代
现在需要在几秒内 再次编译我们的包并运行测试
如你所见 进度条很好 测试结束的很快 因为我们在平行运行它们
让我们再次回到幻灯片
接下来 我要讲一下 Swift 包管理器的设计
SwiftPM 遵循 Swift 的理念 快速 安全 表达能力强 它很安全 因为构建环境是独立的 而且构建项目不能运行任意指令 而快速得益于 使用了对大型依赖图 可扩展的构建引擎 表达能力强是因为 包清单文件使用的是 Swift 语言 这也让你可以使用 已经熟悉的编程语言 接下来 我会向你展示 在创建 Swift 包时 会遇到的各个步骤 首先是配置
就像刚才见到的 SwiftPM 的清单文件 是基于 Swift 的 使用 Swift 让它更加容易理解 因为这样你不用学习任何 新的语言 而且我们还遵循了 Swift 的 API 设计准则 让你觉得更加熟悉 这还让我们可以 利用现有的 为 Swift 写的工具 但是当编写你自己的清单时 你还是应该使用声明式语法 以避免副作用发生
因为 SwiftPM 不能保证 在什么时候或按什么频率 评估你的源代码 左手边 这个例子就没有 完全使用声明式 我们看不到 生成的名字 而它在包里面出现了好几次 相反 在右边就是一个 运用字符串常量的 声明式清单文件 很容易理解 目标是什么
如你所见 不使用声明式语法 会让你的清单 对你和你的用户而言 更难理解
源文件被放在磁盘上 在包中以每个目标命名的 文件夹下 这样就可以上手 并且让包 使用一个常见结构 让你可以更快的导航
包管理器和其他构建工具 总是关注 哪些是用户 指定编写的 哪些是由包管理器 应用的惯例
正如之前所讲 源文件是自动从 盘里的惯例位置提取的 这样你可以很容易的 添加或者移除源文件 而不需要编辑 包清单文件
但是产品和目标 需要指定配置 这样可以更简单的 理解这个包和它的定义 而无需与盘的布局 进行对照
同时 客户仅仅通过看清单 就很容易明白 这个包提供的是什么内容
SwiftPM 同时支持 用其他语言创建源代码 比如 C C++ 或者 Objective-C 并且可以与现有代码整合
但是请注意 我们不支持在同一个目标里 把这些语言和 Swift 混用 接下来 我们看一下 依赖和版本号
为了确保你的包 能够很好的进行错误修补 而不是频繁混乱 Swift 包需要坚持语义版本
这是一个常用标准 把具体语义 与每个版本数的部分 联系起来
主要版本意味着 破坏性改变 需要客户更新代码
这些改变包括 删除现有类型 删除信息 或者改变签名 同时包括 反向不兼容错误修补 或者对现有 API 的行为 做出的重大改变 次要版本是指 以反向兼容的形式 添加的功能
比如添加一个新的 方法或者类型 最后 补丁版本是指 当你做反向兼容错误修补时 需要增加的数字
这让客户可以 可以得到错误修复 而不用担心破坏源代码 SwiftPM 在开始构建前 需要确定包图中所有包的 具体版本 我们要使用叫 依赖解析的过程 它可以让 SwiftPM 查看所有对包的指定要求
并找出和它们兼容的 最新版本 让我们再来看一下 SwiftPM 在这个过程中 都做了些什么 还用刚才的演示
dealer 包有两个 直接的依赖 一个是 SwiftPM 本身 另外一个是 DeckOfPlayingCards SwiftPM 会分析 这些直接依赖的版本 第一个一目了然 因为我们 指定了一个版本
写在了标签中
第二个 我们使用了 from 语法 意味着我们 对次要和补丁部分进行更新 本例中 最后得到的 是 3.1.4 标签 整个过程都是递归的 接下来 SwiftPM 查看所有直接依赖的传递依赖 PM 没有其他的依赖了 所以没有其他什么可做的了 但是 DeckOfPlayingCards 依赖于 fisher-yates 和 playing-card 包 SwiftPM 需要再次解析 这些包的版本 对 fisher-yates 包来说 方法是一样的 因为我们使用的还是 from 语法
在这里的 标签结果是 2.2.5 对 playing-card 包 我们使用的是 upToNextMinor 语法 意味着我们 只更新补丁部分
如果你想对依赖更保守一点 只进行错误修补 那么你应该使用这种语法 在这里的 标签结果是 3.0.2 最后 当考虑目标时 SwiftPM 需要 把要求的产品 和我们解析的包匹配 让我们看一下演示中的 dealer 目标 如你所见 Utility 产品是由 SwiftPM 包提供的
包的其他部分 提供其他产品 依赖解析之后 解析结果被保存在 package.resolved 文件里 这个文件的目的是 让你可以把你的 解析版本分享给 团队其他人或者 继续集成基础结构 这样你就可以得到 可依赖的构建结果 并且你可以选择 什么时候更新依赖 当你想更新时 运行 Swift Package Update 就可以 请注意 包含 package.resolved 的 是最顶层的包 如果有传递依赖包含 package.resolve 文件 它会被依赖解析忽略
接下来让我们看一下 包的构建 SwiftPM 使用 llbuild 作为基础构建引擎 llbuild 是一套构建 构建系统的库 建立在通用目标和 可重复利用的构建引擎之上 这样我们可以进行 更快也更准确的增量构建 Xcode 的新构建系统 也使用该引擎 这也是 Swift 开源项目的一部分
独立的软件开发 再加上详细声明的依赖 保证了 即使有的包要求复杂 也可以安全可靠地 在不同环境下构建和使用
SwiftPM 不会把包 以全局形式安装到系统 它只允许你 使用你指明依赖的包
我们还利用了构建沙盒 这样在构建时 就不会 把内容写入文件系统的任意位置
SwiftPM 不允许 执行任意命令 或者外壳脚本
这让我们可以 完全了解你的构建图 和所有的输入输出 进行快速又准确的增量构建 因为我们知道 你所有的依赖 正如我之前演示时所说 SwiftPM 也支持测试 它建立在 XCTest 框架上 你应该已经很熟悉了 我们支持平行测试 这样你可以更快的得到测试结果
我们还支持测试过滤 这样你可以运行一系列 子测试并基于同一结果 进行迭代 因为我们在扩展 SwiftPM 我们考虑到了 工作流程功能 让你可以在命令行 进行所有的开发 这个功能就是编辑模式 它可以重写某个特定包所有的 传递事件 它创建了一个本地副本 这样可以进行临时编辑 而对传递依赖的 调整可以被测试 而不用把提前转给 包图中所有的包
分支依赖允许 在没有严格版本要求的情况下 依赖包 当你在同时 开发好几个包时 这个很有用
这是只针对开发的功能 所以当你发布标签之前 你需要调整到 特定版本的依赖 本地包让你可以 直接从文件系统 使用包 而不是从 Git 存储库 这很有用 可以让你在初始创建中 创建多个包
最后一个话题是 使用 SwiftPM 和 Swift 语言的新版本 每个新 Swift 版本 会产生一个新版本的 package.swift 清单 API 上一个版本 API 还可以使用 这样你可以利用新的源工具 而不需要更新你的包 或者失去对现有包的访问
采用新的 API 是独立于 将你的包源代码 更改到新的 Swift 语言版本的 若要指定使用的 API 具体是哪个版本 我们要在 package.swift 清单文件的顶层
使用 Swift 工具版本指令 它可以指定 用来处理给定清单所需的 Swift 工具的 最低版本要求 每个包还可以声明 它用来编译源代码的 Swift 语言版本 这是一个列表 通过使用编译指令 你可以对于自己同一版本的包 你可以支持多个版本的 Swift 一个包图可以是 很多不同语言版本的包的集合
今天讲了很多 SwiftPM 如何工作的 接下来 让我们再次 请 Rick 上台来讲一下 未来的展望
谢谢 Boris
Boris 向你们展示了现在 可以做什么 但其实 还有很多潜力 SwiftPM 还是一个新项目 有很多成长空间
Swift 使用了一个 开放演化的过程 意味着任何人 包括你们都可以贡献想法 如果你想得到一些启发 我们也愿意分享一些 我们的想法 虽然它们还没有形成计划 我们分享这些想法 为了让你看到 Swift 包管理器的潜力 也很希望能得到 你们的反馈评论和想法 帮助我们推进这个产品
我今天要讲的 想法分为四个 不同的主题
第一个应该就是 让 Swift 包管理器 和其他工具融合 帮助你发布 包的新版本和配置它们的产品 支持比 SwiftPM 如今能构建的更复杂的包 最后是在包的 发现和信任上的展望 因为 SwiftPM 命令行 体验非常重要 我们希望确保 SwiftPM 能和其他工具融合 比如开发环境 自动化等等
我们已经通过 SwiftPM 基于库的结构 打下了一个基础 SwiftPM 如今还没有 稳定的 API 但是对于那些同 SwiftPM 一起改变的工具 现在已经可以使用和添加了
如果你愿意 在你的开发工具里 为 SwiftPM 构建支持 我们非常欢迎你的贡献和讨论 我们希望让 SwiftPM 成为 开发工具繁荣的生态系统中的一部分 最近在 Swift 论坛上 我们看到的一些请求是 寻找可以用自动工具 编辑 package.swift 清单的方法 而不需要 让用户总是直接 编辑源代码 我们认为让 SwiftPM 支持这个是可行的 可能会通过使用 libSyntax 实现 libSyntax 是一个 在 Swift 开源项目中 开发的库 让你更容易的 在别的工具上理解和使用 Swift 语法
Boris 刚才讲到过 你应该为 package.swift 清单 采用声明式语法 这是另外一个原因 这会让 SwiftPM 可以 更容易的 理解你的清单 并作出自动调整 比如添加新的依赖 或者目标 SwiftPM 还有很多空间 来添加新的功能 帮助 你发布新版本 并部署它们的产品
现在 如果你想 发布一个包的新版本 你需要手动用 Git 标注 如果你想检查发布的标签 也要直接使用Git
我们可以添加新功能 来自动化这一过程 执行额外的杂务工作 验证和其他辅助任务 作为工作流程改进的一部分
我们可以添加的 一个非常有用的功能 就是帮助保持 正确语义版本 我们可以让 SwiftPM 分析 你的新版本包里 API 的差异 并检测你是否在编译时 做出了不兼容的更改 如果做出不兼容的更改 就建议你更新包的主要版本
另外一件可以做的事是 让你可以从 SwiftPM 更容易的部署产品 你也许希望个性化 和库的链接 或者个性化特定配置环境下 的产品布局 本地或者在服务器上 或者你希望 包含版本信息 关于哪些包被构建进产品
或者你希望 把 SwiftPM 关于 你的包的参数用于你的产品 SwiftPM 可以添加新的命令 来支持这些需求
现在用 SwiftPM 已经可以构建很多东西 但是我们希望可以支持 更多有更复杂需求的包
如今最大的缺口 可能就是支持资源 如果你有任何图像 数据 文件或者其他素材 SwiftPM 目前还不能 把它们和你的产品 打包在一起
基础核心库 在今年春天刚刚添加了 跨平台使用资源的 API 如果我们想构建 这个特性 可以让 SwiftPM 使用这一 API
我知道还有一些用户 希望添加对 一些特定编译器标志 连接标志的支持 以及其他 SwiftPM 如今 还不支持的属性 我们希望能 添加一个强大的 构建设置模式 包含条件设置 或者粒度控制 00:29:58.776 --> 00:30:00.146 A:middle 来决定哪一部分的包
有哪些设定值
Boris 刚才还谈到 SwiftPM 构建的独立性 以及它重要的原因
我们不允许你运行 任意外壳脚本 但有一些用户 构建可以在一定程度上个性化 也许是因为 想要个性化语言 或者处理器 他们想运行自己的 文档生成器工具 或者有其他需要添加到 构建过程的步骤 我们认为 SwiftPM 可以安全的支持这些内容 甚至是通过实际的工具包 把新的工具带入 你的构建过程 重要的是 如果我们采用这一新功能 就要确保 任何加入构建过程 的新工具都必须 准确的声明它们的 输入和输出依赖 这样 SwiftPM 才可以继续保持 正确的增量和平行构建
最后 我想说一下 关于包的发现 信任和管理的 前瞻想法 Git 自身支持 它的条款也支持 提供如 TLS 的安全机制 以确保 你在和你认为的 远程储存库接触 但是恶意伪装 可以危害到 远程储存库 并写入恶意内容 事实上 在任何情况下使用第三方代码 你都应该 提高警惕 但是 Swift 包管理器 提供一个很好的机会 让我们构建一个安全功能 确保你得到的是 你所期待的内容
SwiftPM 还可以让 构建中的 package.swift 清单评估 无法绕过安全保护并从你的 文件系统写出内容 或者访问网络 今天我们使用的是 macOS 的沙盒技术 它很棒 但我们同时也想 把这种安全性带入别的平台
很多用户希望 将复刻包变得简单 也许是因为他们想 在包图里对某个包 做私人的个性化处理 又或者是因为 他们想重写 得到这个包的原 URL 这样可以指向 一个他们控制的私人镜像 而不用寄希望于 原来的包永远在那个位置 最后我希望 Swift 包能有一个真正的索引 除了提供 标准化命名空间 让发现新的包更容易 我们还可以为包 提供更多支持 如质量衡量标准等等 比如它的自动测试范围 是怎样的 或者支持用来评估 你考虑使用的 新包的可靠性的方法 我说了很多 但这些只是其中的一些可能性 如果你们感兴趣 我们很希望 听到你的反馈 想法和贡献 让 Swift 包管理器成为 开发者社区里最好的工具 如果希望加入的话 你们应该如何做呢 我想说一下 Swift 的开源过程
我刚才也提到过 包管理器是 Swift 开源项目的一部分 Swift.org 是 一个很好的 了解社区和过程的地方
SwiftPM 使用的是 Swift 语言评估过程 这意味着任何人都可以对 Swift 包管理器的的新功能或者调整 提供建议
不过 在你起草 一个完整正式的提案之前 我建议你 去 Swift 论坛的 包管理器部分 和社区交流一下你的想法 你可以得到很多反馈 能够帮助你完善你的想法 如果你想先 小试牛刀 bugs.swift.org 的 错误追踪器中 有很多的好想法 尤其是那些 标记了 StarterBug 的的错误 因为 正如我所说 SwiftPM 是用 Swift 写的 00:34:02.436 --> 00:34:04.886 A:middle 你会发现它其实很容易上手
当然 如果你在 使用 SwiftPM 时找到了错误 我们鼓励你报到 bugs.swift.org 上 你可以追踪我们是如何解决的 SwiftPM 可以利用 和 Swift 项目相同的 持续集成基础结构 这意味着轮询请求 可以被自动构建 并在合并前进行测试 因为 SwiftPM 代码 有很大的测试范围 我们发现这个 基础结构对我们来说 非常有用
当你准备尝试 最后的调整 你可以在 Swift.org 上 下载 Trunk Snapshot 工具链 它们会定期更新
我们很高兴见到 SwiftPM 社区如今的成长 有180 多个人做出贡献 有些是在错误修复上 有些是在新功能上 Swift 包生态系统 也在以健康的速度增长 很多跨平台包 和公共包 都可以在 GitHub 上找到 这意味着你可以 专注于怎样让你的产品 与众不同 让包的依赖 负责剩下的部分 我建议你现在就 体验一下 SwiftPM 的 一些功能 而它未来还有很大的进步空间 两个建议的功能分别是 命令行实用工具和 针对在服务器上用 Swift 做开发的库
服务器端的 Swift 社区 对 Swift 包管理器 进行了广泛的应用 服务器端的 自己也在很好的成长 现在提供了很多框架 来做网页和后端开发 如果你愿意关注一下 这种方式的话 我觉得你会发现 Swift 是做这种跨平台开发的 很好的语言
但是你也可以 用 SwiftPM 创建 命令行实用工具和库 哪个都可以 上手很容易 只需要打开一个终端窗口 然后在里面运行 Swift 包 如果下次 你想尝试新事物 我建议你试试看 如果你想做出贡献 请到 Swift 论坛 开始对话
如果想来和我们聊聊 明天下午 3 点 我们会在实验室 我很兴奋的想知道 我们能做成什么 以及这个开发者社区一起 可以成就什么 你的贡献能够帮助我们 设计一个很棒的包管理器 对整个 Swift 社区都意义重大
谢谢 祝你享受接下来的 WWDC [ 掌声 ]
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。