大多数浏览器和
Developer App 均支持流媒体播放。
-
创建 Swift 软件包
不论您是要发布代码来在社区中分享,还是只想能方便地整理 app 中的代码,Swift 软件包都可以为您助力。了解如何创建供自己开发工作中使用的本地软件包,如何通过清单文件自定您的软件包,以及如何发布软件包来供他人使用。
资源
相关视频
WWDC22
WWDC21
WWDC20
WWDC19
WWDC18
-
下载
大家好 我叫 Boris 是 Xcode 团队的一名成员 欢迎来到创建 Swift 包的会议 你们可能已经听说过 Xcode 对包的支持 但今天你们将学习 如何创建自己的包
我们今天将主要讨论 五件事情 我们会了解 如何创建自己的本地包
然后了解如何发布它
我们也要告诉你们一些 关于包 Manifest API 的更多信息 以及如何编辑包 最后 我将告诉你们 有关 Swift 包管理器开源项目的信息 我们已经举办过另一场关于包的会议
你们也应该看看那次会议 因为那里有相关信息 例如如何解决包解析冲突 会议内容还包括 包基础知识介绍 提供给初次接触的人
包是与你的团队 一起在工作区 或与更大的开源社区 共享代码的好方法
我们先来看看如何创建自己的本地包 你可以将本地包看作 工作空间中的子项目 它们本质上与平台无关 因此你可以直接 在 Apple 的所有平台上 使用你的代码
它们非常适合重构出可重复使用的代码 它们没有版本化 但是一旦你准备好了 只需几步即可发布它们 我们来演示一下 如何创建自己的本地包 在这个演示中 我们将使用一个 App 显示我工作地点附近几家咖啡馆的午餐菜单 我们有 iOS 和 WatchOS 两种版本的 App 现在这里有这个数据模型 通过 Target Membership 在两个平台之间共享 随着我们不断开发我们的 App
所以我想把它重构成一个本地包 第一步就是 我们转到 File->New->Swift Package 把这个包命名为 FoodNStuff 我们将它添加到现有项目并添加到根管理组中 然后单击 Create 现在 Xcode 为我们创建了包的基本结构 包括 Readme Package.swift Manifest 文件以及 Sources 和 Tests 文件夹
我们从 App 中 找到数据模型代码 然后将其拖入包中 现在我们要将此代码关联到 我们的 App 让我们快速浏览 Manifest 文件 它描述了如何构建包 还有一个名为 Products 的部分 在这儿我们定义了一个库 我们可以把这个库和 App 关联起来 我们将在之后的演讲中 详细介绍 Manifest 文件和 Products 部分 但是现在 我们打开项目编辑器 打开 Targets 中的 iOS App 然后进入 Frameworks, Libraries and Embedded Content 部分 我们点击这里的 + 号 然后从列表中选择 FoodNStuff
我们希望为 watchOS App 执行相同的步骤 所以我们找到对应的 Target 转入同一部分 再次点击 + 号 并将其与我们的 App 相关联
包中还含有一个或多个模块 所以 我们必须将这些模块导入我们的 App 这个例子中 我们只有一个模块 我们进入 iOS App 的代码
在此处导入模块
我们也会为我们的 watchOS App 做同样的事情
现在 由于我们对工作区 进行了一些较大的更改 因此预览暂停了 那么让我们按下 command + option + P 来恢复它 现在我们的 App 就可以正常运行了 因此 只需几步 我们就可以将可重用的代码 在自己的本地包中完成重构 你可能还注意到 我们没有必要明确配置任何有关平台的内容 这是因为包本质上是平台无关的 因此 它们可以依客户的需求而建立 在这种情况下 我们计划同时构建 iOS 和 watchOS App 因此 包被构建了两次 一次用于 iOS 一次用于 watchOS 并且这一切都由 Xcode 自动处理 最后 这为包的发布打好了基础 但在发布包之前 让我们回到幻灯片 了解更多相关信息
你们刚刚了解了本地包 现在让我们来看看如何发布一个包 以便与广大受众分享 在我们看发布包的具体步骤之前 我们必须了解版本控制
更具体地说 是管理 Swift 包的语义化版本控制
它为了确保你可以在 不影响其他内容的情况下 修复依赖项的漏洞 Swift 包遵循语义化版本控制 这是一种广泛的标准 它为版本号 每个部分 赋予特定的语义含义 主版本号象征着对 API 的突破性更改 它需要更新现有客户端 例如 重命名现有类型 移除一个方法或更改方法签名 但这也可能包括 任何不向后兼容的漏洞修复 或对现有 API 主要行为的更改
更新次版本号 是以向后兼容的方式添加功能 例如 添加一个新的方法或类型 在你进行 向后兼容的漏洞修复时 请递增修订号 这使客户在对包进行漏洞修复时 不会产生任何维护负担 主要版本号 0 是一个特殊情况 你可以在开发初期使用 此时对次版本和修订版本的更改也可能会破坏API 这简化了初始的开发过程
在发布包一段时间后 你的客户将期望有稳定的 API 因此在发布最终版之前 你可以使用预发行版本 请求客户测试 API
你可以通过在版本规则中添加预发布标识符 来选择预发布版本 在这个例子中 我使用的标识符为 beta.1
请注意 这种情况下你可以解析预发布版本 但你仍然会得到更新 例如 这里的版本是 beta.6 一旦稳定版本 5 发布 包解析将自动选择稳定版 但是你应该 在完成测试后 删除预发布标识符 我们来看看 下一个演示中 发布包的具体步骤
让我们回到第一个演示结束地方 首先 我将把包拖出项目 在拖动时按住 option 键 就会创建一份拷贝 关闭项目 在 Finder 中打开它 然后连按 Package.swift 文件
这样就可以独立打开包 和打开项目的方式一样
如果我们查看运行目标 可以看到菜单中也有 macOS 和 tvOS 虽然我们之前的开发仅针对 iOS 和 watchOS
这再次强调了包本质上是与平台无关的 无需特殊配置 即可在 Xcode 中为 所有 Apple 平台构建包
现在 既然你正在发布这个包 那么让我们补充一下 Readme 文件 假设这个包提供了 用于表示食物菜单 并从 JSON 中加载的 数据模型 现在 对于真正的包 你希望在 Readme 文件中包含更多信息 例如使用方法 平台限制等 如果你使用了特定平台的 API(如 UIKit) 还需要包含许可协议的信息 但由于这只是一个演示 现在就足够了
你要做的另一件事是添加测试用例 Xcode 已经为我们 创建了一个示例测试用例 但我们想在这里实际测试 我们的数据模型 让我们创建一个 FoodItem 名称为 chick'n 价格为 42 美元 我们设置条件 物品的价格就是 42 美元 现在 如果我们按下 Command + U
我们的包就会构建并进行测试 就像在项目中运行一样 测试已经通过 因此我们可以继续 我们首先为我们的包创建一个仓库 为此 我们可以打开 Source Control 菜单 并选择 Create Repositories 选项 Xcode 已经为我们选中了包 所以我们只需点按 Create 即可 这将在本地创建一个仓库 并提交我们当前的状态 但我们还需要 GitHub 中的仓库 我们也可以在 Xcode 中创建它 切换到源码管理导航栏 在仓库中打开上下文菜单 然后选择 Create Remote 选项 由于我已经在 Xcode 偏好设置中 配置了我的 GitHub 帐户 因此会在此处自动预选 仓库名称可以更改 但我们保持默认 同时也暂时略去可选描述 我们将可见性设置为私密 因为我想暂时与我的团队分享这个包 而不是面向大众 我们点按 Create
Xcode 一步完成了 在 GitHub 上创建仓库 并当前状态推送到 Github 上的任务 现在我们已经发布了我们的包 但我们还想发布我们的第一个版本 为此 返回上下文菜单 并选择 Tag Master 选项 我们想要发布 1.0.0 版本 暂时不填消息文本框 这会在本地创建一个标记 所以我们仍然需要将它推送到 GitHub 我们要返回 Source Control 菜单 选择 Push 选项 要选中 include tags 复选框 以便它们被推送 然后点按 Push
现在我们已经在 GitHub 上 发布了我们的包 让我们来看看 从上下文菜单中选择 View in GitHub 选项
仓库会在此处打开
演示到这可以结束了 但作为最后一步 我想将包的远程版本 重新集成到我们的 之前的午餐 App 中 因此 我点按 Clone or download 按钮 并从此处复制网址 关闭 Safari Xcode 以及 Finder
然后我们回到 Xcode 的欢迎窗口 再次打开 Lunch 项目
在这里 我们打开 File 菜单和 这个新的 Swift Packages 子菜单
此菜单包含几个用于处理包的选项
但我想添加一个包依赖项 我们在这里粘贴网址
Xcode 为我们推荐的 默认版本规则 包括我们刚刚发布的 1.0.0 版本 所以 我们可以点击这里的 Next 包解析完成 现在我们看到了产品的选择 我们希望将库产品与我们的 iOS App 相关联 所以 我们在这里点按 Finish 现在我实际上忘了做一件事 就是删除我们之前的本地包 所以 我现在把它移到废纸篓里 那么此时就正在获取远程版本 我们来看看项目导航栏中的 Swift Package Dependencies 部分 这显示了所有的包依赖项
好了 因为我们 在之前的流程中 关联了产品 所以它已经与我们的 iOS App 相关联 但我们还必须 将它添加到 watchOS App 中 我们需要回到 Frameworks, Libraries and Embedded Content 部分
点按此处的 + 号 然后选择包产品 现在可以回到预览了
恢复预览 我们可以看到它 像之前一样正常运行 因此 只需几步 我们就可以发布一个包 我们回到幻灯片
接下来 我想邀请我的同事 Ankit 上台 向你们介绍一下 包 Manifest API 的更多信息
多谢 Boris Boris 向你们展示了 如何在 Xcode 项目中 使用本地包 以及如何发布它 以与更广泛的受众分享 在本节中 我们将更多的了解 包的 Manifest API 用它来对包进行配置 Swift 包目录中 包含 Package.swift Manifest 文件
Manifest 的第一行 始终是 Swift Tools 的版本 这是构建包 所需 Swift 编译器的 最低版本 我们将在后面的演讲中 详细说明 之后是导入 PacakageDescription 的语句 这是 Xcode 提供的库 其中包含 使用 Manifest 文件的 API
在这之后是 包的初始化语句 一条包初始化语句 可以配置整个包 在本例中 现在只有包的名称 所以我需要添加 Target Swift 包具有 关于 Target 的标准布局
库 Target 位于 名为 Sources 的目录下 每个 Target 应具有自己的子目录 它们需要在 包初始化语句的 Target 部分 进行声明
标准布局非常强大 因为你无需 在 Manifest 中 单独列出源文件 00:15:53.426 --> 00:15:54.446 A:middle 你只需将它们放在正确的目录中
Xcode 就会 自动添加它们 00:15:58.566 --> 00:15:59.636 A:middle 如果我想添加另一个 Target
我可以创建一个 新的子目录 然后在 Manifest 中声明 Target 测试 Target 位于 名为 Tests 的目录下 它们也有自己的子目录 它们在声明时使用的是 testTarget API 并且由于测试 Target 通常是测试另一个 Target 因此你需要声明 对被测 Target 的依赖
这是使用 testTarget API 的 dependencies 参数 来完成的 作为最后一步 我们需要为包 声明产品 产品用于 从包中导出 Target 以便其他包可以使用它们 在本例中 有一个库产品 导出的是一个库 Target 我们刚刚看到了 一个基本的 Swift 包是如何配置的 现在让我们看看 如何在现有的 Xcode 项目中 添加对 Swift 包的支持 我有一个 名为 Menu Downloader 的项目 我一直把它与其他包管理器一起使用 如 CocoPods 和 Carthage 这个项目有一个 Swift Target 一些遗留 C 代码 Xcode 项目文件和一个 CoCoPods 包管理器使用的 podspec 文件 首先需要做的是 添加 package.swift Manifest 文件 为配置 Target 做准备 从遗留的 C 代码开始 我们首先给它一个名称 然后给它一个自定义路径 这么做的原因是 这个 Target 没有放在 标准的 Sources 目录下
我还发现 C 代码中有一个宏 如果被定义 就会下载一个秘密午餐菜单 所以我使用了 cSettings API 定义它 我们可以以用类似的方式 配置 Swift Target 先自定义路径 然后声明对遗留 C Target 的依赖 这个包有两个产品 第一个产品导出 Swift Target 第二个产品导出 C Target 我们需要单独导出 C Target 因为我们的一些用户 可能直接使用 C Target 在这种情况下 他们不需要 Swift 桥接
它还被标记为 dynamic 因为我知道一些用户 有时会加载这个库 现在 让我们看看 如何在包中配置包依赖关系
包依赖关系在一个 名为 dependencies 的部分中配置 它有两个参数 源 URL 和版本要求 在本例中 我使用的是 upToNextMajor 版本要求 根据语义化版本控制 这意味着我的包 需要的 Yams 是从主要版本 2 开始 然后直到下一个主要版本 3
upToNextMajor 是一种比较推荐的 版本要求声明方式 这是因为它 允许你为下一个主要版本 指定最低版本 它足够灵活 可以避免解析时的 潜在冲突 这个参数也可以直接写作 from
还有一些其他类型的版本要求 我们已经看到了 from 和 upToNextMajor
还有 upToNextMinor 它允许你基于次版本号 声明版本要求 如果你想对所采取的更改保守一些 这种版本声明十分有用
其次我们有 exact 的版本要求 这允许我们 将依赖固定到特定版本上 我们不建议使用这种方式 除非你真的需要使用 因为它很可能会导致 包中发生冲突
还有一些 非基于版本的要求 有基于分支的依赖关系 如果你想要开发多个包 并且希望保持它们同步 这将非常有用 并且有基于修订的要求 这有助于 将我们的依赖固定到 特定的修订版
请注意 已发布的包中不允许 使用基于分支 和基于修订的要求 在发布包之前 必须删除所有基于分支 和修订的要求 现在 在选择我们的包依赖之后 我们需要声明 其中一个或多个产品的依赖 在本例里 我在 Swift Target 中 声明对 Yams 产品的依赖 现在让我们回到 Swift Tools 版本
正如我之前提到的 Swift Tools 版本 始终是 Manifest 的第一行
与所有其他 API 一样 PackageDescription API 也 随着时间的推移而发展 你得到的库版本 取决于 Tools 版本
它还参与了 依赖关系解析过程 Xcode 确保所有 包依赖项的 Tools 版本 始终与包的 Tools 版本兼容 最后 它声明了 构建包所需的 最低版本 Swift 编译器
这对于生成良好的诊断非常有用 以防有人试图将你的包 与较旧的不兼容版本的 Xcode 一起使用 正如 Boris 之前提到的 Swift 包总是与平台无关
如果你的包 支持多个平台 并且你有一些特定于平台的代码 我们可以使用 Swift 的条件组合功能 对于支持平台的可用性 Xcode 为每个平台 都分配了默认的部署 Target 你可以在包初始化的 platform 部分中 自定义部署 Target
请注意这不会限制 此程序包可以构建的平台 它只为你列出的平台 进行自定义设置 在本例中 我将 macOS 自定义为 10.15 将 iOS 自定义为 13
如果你当前的 Tools 版本 没有所需的 部署 Target API 你则可以使用基于字符串的形式 我们刚刚提到了很多关于 API 的东西 所有包 Manifest API 都有对应的文档 你可以在模块界面中查看
按住 Command 键 在任何 Manifest 文件中 点按导入 PackageDescription 的语句 来访问模块界面
知道了这些 让我们再次欢迎 Boris 讨论如何编辑 Swift 包 谢谢大家 多谢 Ankit 在你发布包后 过一段时间 为了与你的团队或开源社区共享 你可能需要在 App 的上下文中修改它 那么 我们来谈谈编辑包 在前面的演示中 我在编辑了一些包 其中一个是本地包 它是作为工作空间的一部分构建的 另一个是双击 package.swift 独立打开的 两者都是一直可编辑的 但是其中的包依赖项 被锁定无法编辑 因为它们由 Xcode 自动管理 如果你看看之前的 App 我们依赖 GitHub 上的 FoodNStuff 包 如果我们现在将独立的包 作为本地包 添加到我们的项目中 它将覆盖现有依赖项 而无需进行删除
它的覆盖基于路径的最后一部分 因此 由于这两者都具有相同的最后一部分 因此本地包 将覆盖远程依赖 由于本地包始终可编辑 因此你可以以这种方式 同时编辑 App 和包 我们来演示如何编辑包 再次 我们回到 我们之前的演示中停下的地方
如果你还记得 Swift Package Dependencies 部分 显示了我们添加的包依赖 由于之前我们已经对独立包完成了检查 我们可以将它 拖到我们的项目中
现在 Swift Package Dependencies 部分消失了 因为我们不再使用远程依赖项 我们正在使用本地包
我们的用户要求 我们为午餐 App 提供新功能 他们想看看 他们能吃哪些菜 所以 我们要明确标记 哪种菜是素食者能吃的 哪种不是 值得庆幸的是 我们的数据模型已包含该信息
不是我们的数据模型 而是我们的潜在数据 我们必须更改数据模型 来真正显示信息 进入包目录
打开 FoodItem 类型
我将在这里添加一个新属性
名为 vegetarian 类型是 Bool 拷贝这部分 将它作为参数 添加到初始化中 最后我们在初始化中 设置属性参数 所以现在我们在数据模型中 有关于是否是素食的信息 让我们在 UI 中添加一些内容 以便向用户显示信息
转到我们的 iOS App 的代码 让我们隐藏项目导航栏 获得更多的空间 并恢复预览 以便我们看到 正在处理的内容 我们可以使用跳转栏 来转到 FoodItemRowView 类型 如果我们在编辑器中转到我们的 UI 代码 我们会看到高亮显示的
所以 我已经准备了一个片段 可以为食物添加标签 包含食物名称 并添加是否是素食的表情符号 在文本字段中 使用该标签 让我们恢复预览 然后可以看到 现在每道菜都清楚标明 它是不是素食 因此 通过这些步骤 你可以同时编辑你的 App 和包 我们回到幻灯片
这种覆盖机制 也可用于修改他人的包 如果你需要修复漏洞 或者修改 包中的漏洞
总结一下 我们来看看 Swift 包管理器的开源项目 我们将其简称为 Swift PM Swift PM 已经推出了几年 Xcode 对 Swift 包的支持 也建立在它之上 Swift 是一种跨平台语言 Swift PM 则是 是一个用于 Swift 包的 跨平台构建系统 00:27:29.526 --> 00:27:31.476 A:middle 你可以使用它
在客户端和服务器端 App 之间共享代码 Swift PM 由 Swift 命令下的 四个命令行工具组成 有 swift build 用于构建一个包 有 swift run 用于运行可执行结果 有 swift test 用于运行测试 以及最后的 swift package 用于在包上执行各种 非构建操作 这些命令行工具 可用于为 macOS 和 Linux 构建包
要了解有关 Swift PM 命令行工具的更多信息 及其未来发展的想法 你可以查看 WWDC 2018 中的 Getting to Know Swift Package Manager 会议
当然 你也可以使用 xcodebuild 在命令行或者 CI 上构建包 这也是一种在命令行上 为 iOS watchOS 和 tvOS 构建包的方法 Xcode 中的 Swift 包支持构建在 libSwiftPM 库之上 libSwiftPM 库是开源项目的一部分 libSwiftPM 可用于 支持 Swift 包和 其他 ID 开发人员工具 我们很高兴与社区合作 建立稳定的 API 一个例子是 SourceKit-LSP 它是为 Swift 和 C 语言 实现语言服务器协议 简称 LSP LSP 定义了 编辑器或 IDE 与
例如自动补全 跳转到定义 或查找引用等语言功能 使用 SourceKit-LSP 支持语言服务器协议的编辑器 IDE 就可以为 Swift 包提供这些功能 这是建立在 开源 libSwiftPM 之上的 Swift 包管理器是 更大的 Swift 开源项目的一部分 Swift.org 网站是一个 了解社区和发展过程的好地方
包管理器遵循 Swift 发展过程 就像 Swift 项目的其余部分一样 任何人都可以开发 并最终提交功能 或重大更改
在花时间提交修改之前 请先查看 论坛的包管理器部分 和其他开发者进行交流 并找到提供可行意见或反馈的人 Swift 包目前仅支持 源代码和单元测试
我们期待与社区合作 增加对图像 文本文件 或其他数据文件等资源的支持 我们已经有了 对包资源的提案 你可以关注这个功能的发展 并参与功能改进
同样在 Swift.org 上 我们会定期更新工具 以便你自己 尝试最新的更新
对开源项目的更改 也将成为 Xcode 未来版本的一部分 最后 Apple 平台和 Xcode 现在已提供对包的支持
你可以在项目中查找 可重用的代码 并将其重构到 Swift 包中 我们对 Swift 包 生态系统不断扩大感到兴奋 如果你对 使用或创建包有任何疑问 我们即将推出两个实验室 一个是在今天 12 点 另一个是明天同一时间 非常感谢你们的到来 享受这周剩下的美好时光吧
[掌声]
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。