大多数浏览器和
Developer App 均支持流媒体播放。
-
Xcode 15 的新功能
了解 Xcode 15 中最新的生产力和性能改进。探索代码完成和 Xcode Previews 的增强功能,了解测试导航器和测试报告,并了解有关简化分发过程的更多信息。我们还将重点介绍改进的导航、源代码控制管理和调试。
章节
- 0:00 - Introduction
- 0:39 - Downloading Xcode
- 1:29 - Code completion updates
- 3:45 - What's new in asset catalogs
- 4:30 - Meet string catalogs
- 5:25 - What's new in Swift-DocC
- 7:01 - Meet Swift macros
- 8:40 - What's new in Previews
- 10:00 - The bookmark navigator
- 12:18 - What's new in source control
- 14:50 - What's new in testing
- 17:23 - Updates in the debug console
- 18:37 - Updates in Xcode Cloud distribution
- 19:37 - Signature verification and privacy manifests
- 21:03 - What's new in Xcode distribution
资源
相关视频
WWDC23
-
下载
♪ 悦耳的器乐嘻哈 ♪ ♪ Shilpa Chirackel: 大家好 我是 Shilpa Ryan Golbeck:我是 Ryan Shilpa:今天 我们非常高兴能向你介绍 Xcode 15 的所有功能 Ryan:Xcode 是你开发体验的中心枢纽 在 Xcode 中 我们将你的开发流程的方方面面 集中一处 让你能够轻松愉快地构建 App 同时让你专注于一个工具 今天 我们将谈谈 今年 Xcode 15 的 诸多改进 从编辑 导航和共享开始 再到测试 调试和分发你的 App Shilpa:在为你介绍 Xcode 的新功能之前 我们先要下载它 而获得 Xcode 正式版本的 最佳方式 就是通过 Mac App Store 这可以保证你始终使用 最新版本的工具 并可以利用 最新的功能 去年 为了让上手 更加容易 我们提供了 watch 和 TV 模拟器的可选下载功能 今年 我们更进一步 让所有的模拟器都可以下载 包括 iOS 和 Apple 最 新空间计算平台 让你可以配置 Xcode 以满足需求 现在 你下载 Xcode 之后 它将占用更小的空间 撰写代码也更为容易 甚至可以是在你获得所有模拟器之前 另外 如果你需要 从 Developer 网站 下载 Xcode 比如最新的 Beta 版 你可以预先选择包含哪些模拟器 现在我们有了 Xcode 让我们直接进入 看看源码编辑器里有什么新功能 代码补全可以帮你更快地 获得你想要的代码 并减少错误 在 Xcode 15 中 它变得更加智能 让我们来看看 代码补全利用了新的信息来源 这个是 Backyard Birds 我要先创建一个新的文件 并命名为 PlantSummaryRow 我将添加所需的导入语句 我创建了一个新结构后 代码补全建议 将 PlantSummaryRow 作为类型名称 这是因为它是我创建的文件的名称 让我完成这个文件的实现
我已经完成了实现 一些代码补全的呈现方式 也有所改进 当你调用一个有默认参数的函数时 要准确地得到你想要的参数 可能是个挑战 你可以看到默认参数的 所有可能的排列组合 以帮助你挑选你想要的参数 我要为这个 VStack 添加一个 frame 修饰符 然后按键盘上的右箭头 我要选择我需要的那个 在这里是宽度 代码补全现在 有了更多的上下文意识 通过提供更好的建议 帮助你完善正在撰写的代码 回到 VStack 当我输入一个点来添加修饰符时 填充是置顶建议 因为 Xcode 知道 它是这个视图中 最经常使用的修饰符 但当我给文本添加一个修饰符时 最置顶建议是字体 这些编辑器的建议 也会考虑周围的代码 我已经改变了这个文本的字体 当我想添加另一个修饰符时 置顶的建议是加粗 因为我不会在处理文本时 使用同一个修饰符两次 下面是另一个例子 在这个文件中 我使用 CLLocation 来寻找我的鸟在哪里 因为我已经输入了纬度 它会建议我输入经度 因为这两个属性 通常是搭配在一起的 所有这些意味着 你会有更好的置顶建议 使你能更快地输入更安全的代码 嘿 Ryan 我听说我们也在为资源目录 带来了强大的补全功能 能请你给我深入介绍一下吗? Ryan:好的 Shilpa 颜色和图像资源 现在由 Swift Symbols 支持 这意味着 它们现在可以用代码完成了 在我的资源目录中 我有一些自定义的颜色和图像 Xcode 15 自动 为它们生成了符号 我可以在我的代码中引用这些符号 而不用引用字符串名 如果我将这个图像的名字改成 MultipleClouds 并建立我的项目 我在另一个使用该资源的文件中 遇到了问题 现在可以通过代码补全来纠正它 这些符号已经保证了类型安全 所以我不必担心在运行时会神秘地 丢失颜色或图像 Xcode 15 也为你的本地化体验 带来了目录的能力和灵活性 字符串目录将你的本地化 集成一处 让你可以集中来审查和更新它们 首先 你需要将项目转换为使用字符串目录 通过选择 Edit > Convert to string catalog 来实现 然后 就会出现一个表 显示所有 可以迁移的 Storyboard、.strings 和 .stringsdict 文件 迁移完成后 你所有的翻译 都会被组织到一个编辑器中 在左边的侧边栏中 你可以查看所支持的 每种语言的翻译进度 而且保持更新很容易 每次构建时 所有的字符串 都会直接从源代码中提取 当新的字符串被添加或删除时 编辑器会对受影响的语言进行注释 并对相关字符串进行标记 如果现在打算着手迁移 请查看"发现字符串目录"讲座 Shilpa 今年 Xcode 在文档方面有什么新内容? Shilpa:有很多 清晰而简明的代码 在文档的帮助下会变得更加完美 无论你想对未来的自己 还是你的 API 消费者 解释什么 写好文档是关键 出色的文档应该有出色的介绍 Xcode 15 有美观的新风格和间距 让文档更容易阅读 但最大的改进是一个新的助手 它可以显示你文档的实时预览 在制作文档时 我可以通过选择 Editor > Assistant > 然后在跳转栏中 选择 Documentation Preview 来显示助手 当我在源码编辑器中输入时 预览就会实时更新 这将准确地显示我的文档 在完全建成的文档档案中的样子 我将添加一个代码例子 来展示它在实践中如何使用 我先写"Use this initializer to display an image of a given bird" 然后我粘贴我的代码例子 由于这个例子涉及到 UI 我将添加一个截屏 说明所产生的视图的样子 我可以引用 名为 BirdIcon 的图片 因为它包含在我的文档目录中 新的文档预览帮助很大 它可以确保你的文档 完全按照你想要的方式呈现 如果你像我一样 热衷于编写文档 请观看 "使用 Swift-DocC 创建富文档"讲座 以进一步了解 与文档同等重要的是 你的代码应该是简洁易懂的 今年 Swift 更新了 一个强大的新语言功能 Swift 宏 宏让 API 更具表现力 有助于消除重复代码 Xcode 的集成让你对宏完全可见 让你像对待 App 中 所有其他代码一样 对待宏生成的代码 宏是 SDK 中 Swift 包的一部分 现在 我们在 Apple 自己的一些框架中 利用了宏的力量 如 Swift 标准库、foundation 和新的 Swift 数据框架 我也可以创建自己的宏软件包 与他人分享 要创建一个软件包 我会使用快速操作 这是一个新功能 让我只需按下 Command-Shift-A 即可访问 Xcode 所有菜单选项 新的宏软件包拥有一个不错的示例 来帮助我开始 我已经创建了一个宏软件包 EnumHelper 在 EnumHelper 中 我把 CaseDetection 作为宏来实现 宏的美妙之处在于 它能生成正常的 Swift 代码 它会提供的代码封装 并整齐地收起来 当你想看看宏在做什么 或者想在宏生成的代码中 进行调试时 你可以在快速操作的帮助下 直接展开宏 如果你需要调试 你甚至可以 在宏里面的代码上设置断点 请观看"展开 Swift 宏"讲座 以获得对 Swift 宏 更深入的技术理解 掌握了这些新知识 如果你想从头开始编写一些宏 可以跟着"编写 Swift 宏"讲座开始 让我们来探索一下 Xcode 中 另一个利用宏的领域 即预览 在宏的帮助下 记住新的预览 API 容易又简单 我将通过输入 #Preview 来添加一个预览 我想预览账户屏幕 App 详情栏有各种状态 我可以通过创建另一个预览 来显示这些状态 我能够看到这两种情况 但现在 UI 中有两个预览 为了区分它们 我将添加一个标题 “Placeholder View”
稍等片刻 还有更多的改进 我们将把预览带到 UIKit 和 AppKit 中 因此 即使是在我的 旧项目 Food Truck App 中 我也可以为 UIViewController 添加一个预览 并像在 SwiftUI 中一样 快速迭代 接下来 让我们来看看 如何开发带有预览功能的小组件 该 API 还为构建基于时间的小组件 引入了新的工作流程
画布上 有一个显示所有条目的新区域 当我浏览它们时 我可以看到小组件的过渡动画 请观看 "用 Xcode 预览构建程序化的 UI"讲座 了解如何在你的项目中 采用令人兴奋的新预览功能 接下来交给 Ryan 让他谈谈导航方面的改进 Ryan:谢谢你 Shilpa 随着项目的开展 它变得更加复杂 让你很难在一个任务中 跟踪你想参考的地标 为了提供帮助 Xcode 15 引入了书签导航器 我将通过点击源代码管理导航器 旁边的按钮来打开它 我一直在向我的代码中 需要添加文档的地方添加书签 我想在这个文件中再添加一个 这很容易做到 我只需要右击这个位置 选择书签
该书签出现在导航器中 并带有它的位置预览 如果我想的话 我可以通过点击它 并输入不同的描述来改变这个显示 Xcode 用我的描述 注释了一行代码 让我很容易看到并想起 我想让它做什么 我的书签列表在增加 但我可以按我喜欢的方式 对它们进行排序或分组 来管理它们 我想把所有 与文档有关的书签放在一起 我会选择我感兴趣的书签 通过二次点击 打开上下文菜单 选择 New Group From Selection 这会创建一个新组 我称之为 “Places to Add Documentation” 书签在我的代码中 是不错的提醒事项 它们也可以作为待办事项清单使用 我可以通过点击它的左边 把它标记为完成 或者我可以通过在上下文菜单中 选择 Delete Bookmark 来彻底删除它 这会删除编辑器中的书签注释 不过 代码行 并不是我唯一可以做书签的东西 书签也是一种 跟踪 Find 查询的好方法 在 Xcode 15 之前 我在我的代码中添加过待办事项 但很难找到它们 所以我在书签中添加了查询 来找到它们
但是我可以将 Find 查询加入书签 我想在我的代码中保留一个列出所有 视图修改器的方便列表 我将使用 新的 Conforming Types 查询 来查找所有 符合 viewModifier 协议的情况
然后 我可以通过 在结果中点击右键 选择 Bookmark Find “viewModifier” 我的查询可以在书签导航器中使用 如果我的查询结果有变化 我只需点击一下书签旁边的刷新按钮 就可以刷新列表 Xcode 15 的新书签导航器可以 跟踪你的工作 这样你就不必跟踪了 让你可以关注手头的工作 开发的另一个重要部分 是分享你的工作 将你的更改汇集在一起 特别是在制作提交 与你的同事分享时 它可能与更改本身一样重要 Xcode 15 引入了新的更改导航器 和提交编辑器 它们一起使用 是查看所有更改的好办法 我一直在为项目添加文档 我可以在源控制导航器中 查看这些更改 首先你会注意到对每个文件状态的 报告和展示的改进 我的阶段性修改 显示为文件名旁边的一个图标 我想开始审查这些更改 所以我将点击未提交的修改项目 来调出提交编辑器 现在我可以在一个滚动的视图中 查看我所有的修改 每部分都显示了足够的上下文 以了解周围的代码 如果我想看到更多 我可以拖动柄 以显示更多文件 每一个更改 都会在源码编辑器中显示 让我能够使用我所习惯的 注释和控件 在审查过程中 我注意到 在 BirdsNavigationStack 文件中 有一个问题 我好像在文档中打错字了 不过我不用离开视图就能解决它 Xcode 处理了我的更改 并删除了这个问题 我的编辑会变为未暂存 在更改栏中立即显示出来 状态指示器 突出显示 BirdsNavigationStack 现在同时进行了 已暂存和未暂存的变更 我想在下一次提交中加入我的修改 所以我要点击 修改内容旁边的变更栏 并选择 Stage Change 我还注意到 我不小心暂存了 一条用于调试的日志语句 我会再次使用变更栏 把这个变更改为未暂存 这些暂存控件很容易使用 而且它们被整合到了 Xcode 中 我已经准备好签入我的变更了 我将首先在提交消息框中 添加一个描述 然后点击 Commit Xcode 创建了我的提交 并立即在提交查看器中 打开它 总结了它所包含的内容 最后 我可以与组员 分享我的提交了 我会点击 我的提交旁边的状态指示器 选择 Push 然后按照提示操作 这些源代码控制功能是很好的改进 可以让你在 Xcode 15 中 保持专注 嘿 Shilpa 我想我们也有一些 有助于测试的新功能 你能给我们讲一下吗? Shilpa:好的 Ryan 测试是发布高质量 App 的 重要部分 它可以让你快速捕捉回归 并在你增加 App 复杂性的同时 保证其质量 测试在今年有了很大的改进 首先是更新了测试导航器 我们用 Swift 完全重写 使得它更加高效 在实时运行或报告你的测试结果时 Xcode 的速度提升了 45% 测试导航器 围绕你的测试计划进行组织 使其更容易找到你关注的测试 你还可以使用筛选 来寻找基于任何结果类型的测试 如预期失败 当你在 Xcode 或 Xcode Cloud 中运行测试时 测试报告会帮助你探索结果 显示你下一步的重点 它从整个测试运行的高级摘要开始 其中包括 Insights 一个基于模式的结果分析 在 Test 部分中 你可以了解测试的表现 很容易弄清楚 在不同的设备和配置中 有多少测试通过和失败 Insights 分析测试结果 以识别以前可能难以看到的 潜在相关失败 它还会提醒我们 测试运行可能会导致整个套件 花费更长的时间来返回结果
第二个 insight 让我很在意 测试在尝试轻点 Account 按钮时 失败了 我想进一步调查这个问题 从概述中 我可以导航到测试列表 它显示了所有的测试运行 有结果类型 运行目标 和测试计划配置的筛选 我看到测试在轻点 Account 按钮时失败了 这是多种语言版本出现的 相同错误信息 为了进一步了解 我可以查看单个的类 或者导航到各个方法专用的 Test Details 视图 Test Details 视图 包含不同方式的 探索结果数据的标签 包括所有 运行的明细和专门的性能指标标签 有了新的自动化探索器 调试 UI 测试失败 变得前所未有的有趣 探索器是交互式的 所以你可以观看测试回放 或者浏览时间线 触摸或鼠标事件覆盖在视频上 在故障点 例如 我的测试 未能轻点 Account 按钮时 我可以检查我的 App 的 UI 层次结构 这会让修复 UI 测试的失败 变得更加容易 想要深入学习 请观看 "使用 Xcode 测试报告 更快地修复失败"讲座 以进一步了解 让我们回到 Ryan 这里 谈谈调试 Ryan:测试和调试是相辅相成的 它们都是为了制作高质量的 App 调试在今年也得到了 一些很大的改进 首先是 OSLog 集成到了 Xcode 中 OSLog 是捕捉 运行时信息的出色工具 它可以提供 结构化和可定制的日志机制 让你的日志输出有条理 而 Xcode 15 的控制台 引入了对 OSLog 的全面支持 包括对日志数据 进行复杂筛选的能力 比如子系统类别和严重性 日志的表现形式 比以往任何时候都要简洁 重点放在你的日志内容上 额外的数据被整齐地隐藏起来 每个日志条目的背景颜色 显示其严重程度 使其很容易扫描长的日志输出流 以寻找重要信息 虽然元数据字段默认是隐藏的 但只需点击几下就能出来了 你可以只选择你想看的字段 当你要寻找特定的内容时 筛选字段可以让你缩小寻找范围 你可以筛选元数据或日志的全文 还有一个我很喜欢的功能 你可以直接从一个日志条目 跳回到创建它的代码行 我们在"用结构化日志进行调试"讲座中 对这些日志功能进行了深入的讲解 最后 让我们来谈谈分发 分发是指将你的 App 推向全世界 推给你的组员 你的 Beta 版测试者 和你的用户 Xcode 15 有一些改进 让这个过程更容易更安全 让我们从 Xcode Cloud 开始 Xcode Cloud 是分发 你 App 的好方式 它可以自动 为你管理构建版本 App 签名 和分发配置文件等事项 今年 Xcode Cloud 增加了两个可以为你处理的细节 首先是 TestFlight 测试细节 Xcode Cloud 增加了对你的源代码中 测试备注的支持 这些备注会被自动附加到 TestFlight 构建中进行分发 因此 备注会和你的 App 一起出现在 测试人员面前 其次 Xcode Cloud 现在支持 对你的 Mac App 进行公证 你只需要在你的工作流程中 添加公证后置动作 Xcode Cloud 将完成剩下的工作 你的构建完成后 你的 App 将被自动公证和封订 准备好被下载 公证你的 App 对你的用户来说至关重要 它让用户知道 你的 App 没有被篡改过 但同样重要的是 你可以信任 你所依赖的 SDK 和框架的完整性 为了提供这种保证 Xcode 为 XCFrameworks 引入了签名验证 作者可以对他们的框架内容 进行数字签名 你可以在 Xcode 中 验证这些签名 框架检查器有一个新的签名切片 它可以告诉你是谁制作 并签署了该框架 Xcode 会记住这个身份 因此 如果它在更新框架时发生了变化 你会得到一个 关于这个问题的明确警告 但并不止于此 App 作者现在可以在框架中 包含一个隐私清单 这个清单用来详细说明框架是如何 使用和保护敏感数据的 因为隐私清单 是与框架捆绑在一起的 所以它也是签名包的一部分 你可以相信其内容 直接来自 App 作者 我可以使用 Xcode 将所有的清单 总结成我的 App 的 完整隐私报告 下面是我生成的一份报告 这份报告的目的是为了方便 我在 App Store Connect 中 填写隐私标签 确保我向我的用户提供准确的信息 Apple 正在 与影响隐私的 SDK 合作 以确保你所有的关键依赖 都能提供这种有价值的信息 我们在"用数字签名 验证 App 的依赖关系"讲座 和"开始使用隐私清单"中 更深入地讨论了这些话题 在向用户分发 App 时 隐私清单是一个很好的工具 当你在进行错误修复 或处理新功能分支时 你希望将你的 App 分发给你的队友 并且只分发给你的队友 Xcode 15 现在支持 TestFlight 内部测试分发选项 TestFlight 内部构建 只对你的团队可用 所以你绝不会 不小心将其发布给客户 创建它们很容易 只需在通过 App Store Connect 分发你的 App 时 选择 TestFlight internal testing 选项
但实际操作比这还简单 Xcode 现在捆绑了 一套最常用的分发方法 和推荐设置 第一步 选择这些新选项中的任何一个 包括 TestFlight internal only 第二步 点击 Distribute 这样就完成了 没有第三步 如果你要 通过 App Store Connect 分发 你还会收到关于你的构建状态的 桌面通知 所以 当你的 App 准备好进行测试时 你会立即得到通知 这些更新使得迭代 和快速分发你的 App 变得很容易 这使得与你的队友 测试人员 和用户的密切合作变得快速顺畅 观看"使用 Xcode 和 Xcode Cloud 简化分发"讲座 开始探索这些功能 这就是对 Xcode 15 中的 新内容的快速概述 它更容易获得 使用更快捷 并有大量的改进 让你的开发更集中 更流畅 更有趣 Shilpa:去下载 Xcode 15 吧 这样你就可以开始尝试 这些很酷的新功能了 感谢收看 ♪
-
-
1:52 - Code Completion - PlantSummaryRow
import Foundation import SwiftUI import BackyardBirdsData import LayeredArtworkLibrary struct PlantSummaryRow: View { var plant: Plant var body: some View { VStack { ComposedPlant(plant: plant) .padding(4) .padding(.bottom, -20) .clipShape(.circle) .background(.fill.tertiary, in: .circle) .padding(.horizontal, 10) VStack { Text(plant.speciesName) } } } }
-
3:28 - Code Completion - Latitude & Longitude
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { if let mostRecent = locations.last?.coordinate { logger.debug("Handled coordinate update: \(mostRecent.latitude)") } }
-
6:18 - BirdIcon Documentation
/// Create the bird icon view. /// /// The bird icon view is a tailored version of the ``ComposedBird`` view. /// /// Use this initializer to display an image of a given bird. /// /// ```swift /// var bird: Bird /// /// var body: some View { /// HStack { /// BirdIcon(bird: bird) /// .frame(width: 60, height: 60) /// Text(bird.speciesName) /// } /// } /// ``` /// /// ![A screenshot of a view containing a bird icon with the bird's species name below it.](birdIcon)
-
7:37 - CaseDetection Macro
extension TokenSyntax { fileprivate var initialUppercased: String { let name = self.text guard let initial = name.first else { return name } return "\(initial.uppercased())\(name.dropFirst())" } } public struct CaseDetectionMacro: MemberMacro { public static func expansion< Declaration: DeclGroupSyntax, Context: MacroExpansionContext >( of node: AttributeSyntax, providingMembersOf declaration: Declaration, in context: Context ) throws -> [DeclSyntax] { declaration.memberBlock.members .compactMap { $0.decl.as(EnumCaseDeclSyntax.self) } .map { $0.elements.first!.identifier } .map { ($0, $0.initialUppercased) } .map { original, uppercased in """ var is\(raw: uppercased): Bool { if case .\(raw: original) = self { return true } return false } """ } } } @main struct EnumHelperPlugin: CompilerPlugin { let providingMacros: [Macro.Type] = [ CaseDetectionMacro.self, ] }
-
8:07 - Using CaseDetection Macro
@CaseDetection enum Element { case one case two } var element: Element = .one if element.isOne { // Handle interesting case }
-
8:50 - New Preview API
#Preview { AppDetailColumn(screen: .account) .backyardBirdsDataContainer() } #Preview("Placeholder View") { AppDetailColumn() .backyardBirdsDataContainer() }
-
9:22 - UIViewController Preview
#Preview { let controller = DetailedMapViewController() controller.mapView.camera = MKMapCamera( lookingAtCenter: CLLocation(latitude: 37.335_690, longitude: -122.013_330).coordinate, fromDistance: 0, pitch: 0, heading: 0 ) return controller }
-
17:34 - OSLog
import OSLog let logger = Logger(subsystem: "BackyardBirdsData", category: "Account") func login(password: String) -> Error? { var error: Error? = nil logger.info("Logging in user '\(username)'...") // ... if let error { logger.error("User '\(username)' failed to log in. Error: \(error)") } else { loggedIn = true logger.notice("User '\(username)' logged in successfully.") } return error }
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。