View in English

  • 打开菜单 关闭菜单
  • Apple Developer
搜索
关闭搜索
  • Apple Developer
  • 新闻
  • 探索
  • 设计
  • 开发
  • 分发
  • 支持
  • 账户
在“”范围内搜索。

快捷链接

5 快捷链接

视频

打开菜单 关闭菜单
  • 专题
  • 相关主题
  • 所有视频
  • 关于

返回 WWDC19

大多数浏览器和
Developer App 均支持流媒体播放。

  • 简介
  • 转写文稿
  • 创建 Swift 软件包

    不论您是要发布代码来在社区中分享,还是只想能方便地整理 app 中的代码,Swift 软件包都可以为您助力。了解如何创建供自己开发工作中使用的本地软件包,如何通过清单文件自定您的软件包,以及如何发布软件包来供他人使用。

    资源

      • 高清视频
      • 标清视频
    • 演示幻灯片 (PDF)

    相关视频

    WWDC22

    • 在服务器端开发中运用 Xcode
    • 构建 Swift 软件包插件

    WWDC21

    • 使用精选集探索和管理 Swift 软件包

    WWDC20

    • 将二进制框架作为 Swift Packages 发布
    • 建立可扩展企业App套件
    • Swift 软件包资源和本地化

    WWDC19

    • 在 Xcode 中采用 Swift 软件包
    • Swift 中的二进制框架
    • Swift 新功能

    WWDC18

    • 了解 Swift Package Manager
  • 搜索此视频…

    大家好 我叫 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 点 另一个是明天同一时间 非常感谢你们的到来 享受这周剩下的美好时光吧

    [掌声]

Developer Footer

  • 视频
  • WWDC19
  • 创建 Swift 软件包
  • 打开菜单 关闭菜单
    • iOS
    • iPadOS
    • macOS
    • Apple tvOS
    • visionOS
    • watchOS
    打开菜单 关闭菜单
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • SF Symbols
    打开菜单 关闭菜单
    • 辅助功能
    • 配件
    • App 扩展
    • App Store
    • 音频与视频 (英文)
    • 增强现实
    • 设计
    • 分发
    • 教育
    • 字体 (英文)
    • 游戏
    • 健康与健身
    • App 内购买项目
    • 本地化
    • 地图与位置
    • 机器学习
    • 开源资源 (英文)
    • 安全性
    • Safari 浏览器与网页 (英文)
    打开菜单 关闭菜单
    • 完整文档 (英文)
    • 部分主题文档 (简体中文)
    • 教程
    • 下载 (英文)
    • 论坛 (英文)
    • 视频
    打开菜单 关闭菜单
    • 支持文档
    • 联系我们
    • 错误报告
    • 系统状态 (英文)
    打开菜单 关闭菜单
    • Apple 开发者
    • App Store Connect
    • 证书、标识符和描述文件 (英文)
    • 反馈助理
    打开菜单 关闭菜单
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program (英文)
    • News Partner Program (英文)
    • Video Partner Program (英文)
    • 安全赏金计划 (英文)
    • Security Research Device Program (英文)
    打开菜单 关闭菜单
    • 与 Apple 会面交流
    • Apple Developer Center
    • App Store 大奖 (英文)
    • Apple 设计大奖
    • Apple Developer Academies (英文)
    • WWDC
    获取 Apple Developer App。
    版权所有 © 2025 Apple Inc. 保留所有权利。
    使用条款 隐私政策 协议和准则