这场 《回顾 WWDC 23》把四种开发经历放在一起:学生怎样完成一个教学作品,长期使用 SwiftUI 的开发者怎样评估新框架,独立开发者怎样把现有逻辑搬到服务端,以及空间计算能否成为值得长期投入的平台。
录播由 T 技术沙龙账号于 2023 年 6 月发布,时长约 2 小时 51 分。技术评价要放回当年的首发和 Beta 语境:iOS 17 尚未正式发布,SwiftData 刚出现,Apple Vision Pro 也刚公布。嘉宾对未来的期待,不能当作后来产品已经实现的能力。
学生作品的起点,是一个自己没有理解透的问题
开场的学生分享来自一位学生开发者。他在操作系统课程中接触调度算法,课后再看文字讲义,仍觉得抽象。与其只背不同算法的定义,他想做一个能操作的教学工具,让任务怎样排队、怎样获得计算资源、怎样影响性能,都能在屏幕上看见。
作品为六种调度算法分别安排简介与模拟。彩色长块代表不同任务,用户可以加入新任务,观察执行过程,同时查看性能指标。简介解释算法怎样工作、为什么出现;模拟则让读者改变条件,看到选择产生的后果。它不是把教科书截成几个页面,而是让用户带着问题做一次实验。
开发中,他采用前一年发布的 Layout、Table 和导航 API,让任务块自动补齐空位,让数据以表格呈现,并组织不同章节。这些技术服务于可理解性,不是为了把 API 名称塞满作品。即便评审或使用者不了解操作系统,也应能从日常电脑同时做多件事的例子进入,再由提示与按钮知道下一步可以试什么。
他花了大量准备时间重新学习调度相关知识,才开始组织教学内容。这个顺序很重要:能做出动画,不代表已经准确解释了算法。对于教育作品,内容是否正确、例子能否体现差异,与界面是否漂亮同样重要。
分享最后给出参赛建议:讲清作品目的、技术选择和个人投入,也让评审能发现那些不容易一眼看见的设计。但他马上补充,这些是获奖后的个人复盘,并不是官方评分捷径。不同作品可以在技术、艺术或想法上各有长处,不应被一份“获奖模板”限制。他还展示自己前一年观看 WWDC22 Playground 的截图:当时坐在屏幕前听别人分享,一年后成为台上的讲者,这种变化正是社区交流留下的具体影响。
Observation:先弄清楚哪个状态真的影响了界面
14:58 开始,SwiftUI 分享嘉宾用大量小例子讲 SwiftUI 当年的变化。他先说明,这不是让观众当晚记住所有方法,而是建立一张地图:以后遇到某个问题,知道系统可能已经提供了新的入口。
他最重视的数据流变化是 Observation。旧的 ObservableObject 用法中,一个对象发出变更信号,可能让依赖它的多个视图重新计算,即使其中一些视图没有使用发生变化的属性。新机制让 SwiftUI 在执行视图时跟踪实际读取了哪些属性,从而缩小相关变更的影响范围。这里说的是更新依赖与计算,不是承诺某个属性变化就只绘制一个像素,也不是一次解决所有性能问题。当年官方课程解释了这种按访问建立观察关系的方式。
宏让常见模型声明更简洁,但数据的所有权仍需清楚。分享把几种用途拆开:视图拥有的状态、通过环境传播的对象,以及需要给输入控件提供双向绑定的属性。@Bindable 的作用是形成绑定,不是替代所有对象生命周期管理。与其机械把旧属性包装器逐个改名,不如先问对象由谁持有、谁只读它、谁会修改它。
SwiftUI 分享嘉宾提醒旧项目要评估系统版本和迁移成本。这种谨慎是合理的,不过不能把它概括为新旧观察模型绝对无法在同一应用中使用。Apple 的迁移文档说明可以渐进改变代码;具体视图仍要按相应模型的观察机制处理。能逐步迁移,与迁移不需要设计,是两回事。
动画不只更丰富,也可以更精细地限定作用范围
34:18 左右,演示转向动画。SwiftUI 分享嘉宾喜欢新的弹簧预设,因为开发者不必先掌握所有物理参数,也能得到比较自然的开始与结束。弹簧动画并非到 2023 年才第一次出现;本年的变化是新的表达、默认行为和更易用的参数组织。
更重要的问题是动画影响谁。过去给一段状态修改加动画,可能连带影响并不想一起变化的部分;位移与缩放若要使用不同速度或不同曲线,也容易互相干扰。新的作用域表达让开发者更明确地把某个动画应用到某组变化上。高级场景还可以通过事务和自定义动画进一步控制,但一般产品不必为了用新 API 而把简单效果复杂化。
随后他比较阶段动画和关键帧动画。阶段动画描述一组依次到达的状态,适合连续完成几个动作;关键帧则把某个值在时间线上怎样变化写得更细,多条轨道可以共同控制不同属性。前者方便表达过程,后者适合精确编排。动画不是越复杂越好,频繁更新的成本与使用目的需要一起考虑。
视觉效果部分继续连接到几何信息、shader 和符号动画。visualEffect 让一些基于视图尺寸与位置的效果少写中间传值代码,但其闭包支持的效果有范围,并不是所有修改器都能任意放进去。shader 提供了颜色、形变等表达能力,也仍然需要相应图形知识;SF Symbols 的动画则把常见反馈做成容易预览和调用的能力。它们降低重复劳动,不自动决定什么动效对用户有帮助。
滚动、表格与桌面细节,让应用少一些绕路的实现
52:15 开始,滚动容器成为另一个重点。演示把目标识别、程序控制位置、翻页、滚动过程中的状态变化、内容边距与裁切放在一起。单看每一个都是小功能,组合起来却能省去过去测量尺寸、传递位置和额外包裹视图的许多工作。
例如,元素接近边缘时改变位置或透明度,需要知道它处于滚动容器的什么阶段;按按钮滚到某项,需要稳定识别目标;阴影延伸到容器外时,还要决定是否裁切。不同问题由不同接口解决,不能把“加一个滚动修改器”当成所有布局问题的万能答案。SwiftUI 分享嘉宾还提醒列表结构与元素标识会影响性能,这需要结合具体容器和数据测试,不能从一个例子推出所有嵌套 ForEach 都失效。
前后穿插的小更新也围绕实际应用需要:表格的折叠、列标题、顺序与选择状态,让数据密集的界面更好组织;容器相对尺寸减少常见布局计算;形状布尔运算和不同圆角提供更直接的表达。文字缩放与特定语言的排版调整,则说明同样的视觉尺寸不一定适合所有书写系统。
在资源和交互上,生成图片与颜色资源符号可以减少拼错字符串的问题,但资源是否存在、目标是否正确仍需验证。持续按压按钮、悬停、键盘和焦点,让 iPad 与 Mac 上的交互更接近用户熟悉的桌面习惯。Inspector 为细节面板提供跨平台容器,空内容视图、设置窗口与窗口关闭等接口则补上常见流程。分享也保留了某些 Beta 功能暂时未正常工作的观察,没有把预览体验写成正式版质量结论。
SwiftUI 分享嘉宾最后拿发布前的愿望清单复盘:属性级观察和部分列表优化让他满意,复杂手势、文字输入和向旧系统兼容仍留下期待。这是一位开发者从自己长期问题出发的取舍,不是声称当年所有输入控件毫无变化,或每项新功能都绝不兼容旧版本。完整能力范围可对照当年的 SwiftUI 总览。
SwiftData:声明更像 Swift,持久化问题仍然存在
1:09:20 起,讨论转到 SwiftData。过去通过模型编辑器描述实体与关系,再由工程生成对应类型;新的方式把模型、属性规则和关系更多放回 Swift 代码,以宏减少样板。容器、上下文、查询与迁移也得到新的接口。
SwiftUI 分享嘉宾的判断很有层次。一方面,熟悉 Core Data 的人容易看懂这些概念,新写法确实更顺手;另一方面,初学者不应把“声明短”误认为无需学习持久化。什么时候保存、关系怎样变化、数据模型升级后怎样迁移,仍是产品必须回答的问题。#Predicate 等表达也有自身范围,不能因为长得像普通 Swift 闭包,就假定任意业务逻辑都能转换成存储查询。
他对第一版的担心集中在与既有工程共存、复杂能力是否齐全,以及同步需求能否满足。这里应保留谨慎,收窄绝对判断。SwiftData 建立在 Core Data 已有持久化技术基础上,不宜写成把整个底层从零重写;但这也不意味着应用绝不会丢数据,或两套公开 API 的能力完全相同。
Apple 的 2023 年迁移课程明确讨论了逐步采用与共存,同时要求处理类名冲突、保持两套模型一致,并管理版本。这与嘉宾提醒的维护负担并不矛盾。是否采用,应看所需能力和迁移验证,而不是“新的就全部替换”或“旧项目完全不能用”二选一。对几年后会怎样、是否会改写底层的期待,仍属于当时的预测。
为什么 Kevin 把应用逻辑搬到 Swift 服务端
1:20:10 开始,Kevin 从自己的日语学习产品讲起。他原本希望应用能离线、长期独立运行,但语法分析模型更新后,未升级应用的用户无法及时得到新结果。这个需求使他考虑把一部分处理放到服务端。
他过去用过多种后端框架,也喜欢脚手架与约定带来的效率。最终选择 Swift,一个关键原因是已有业务逻辑已经用 Swift 实现:把合适部分整理成 package,可以减少整套重写。类型检查、调用已有原生库以及自己熟悉的语言表达,也是他的考虑因素。
非阻塞 I/O 被他比作餐厅服务员:一桌还没准备点餐,不必一直站着等待,可以先服务其他桌。这个比喻帮助区分等待与执行,却不等于所有服务端代码自动不会阻塞,也不等于其他语言不能处理并发。录播里对语言、框架和内存的强烈好恶,属于他的使用经历。
他报告自己的场景中基础设施成本显著下降,随后也明确提到代价:第三方服务未必提供 Swift SDK,懂客户端 Swift 的同事未必懂服务端的数据、协议与运维。这里的成本收益不能当作跨语言基准,更不能承诺任何项目迁移后固定节省某个百分比。选择熟悉的语言能省下一部分成本,也可能把成本转移到生态整合与招聘上。
用一个微博式小例子连接模型、数据库与接口
1:30:47 的工作坊选择 Vapor,建立用户与帖子的简单关系。它是本场示例所用框架,不是当时或今天唯一可用的 Swift 服务端路线。
Kevin 先从普通 Swift 的思路列出用户与帖子需要哪些信息,再说明 Fluent 中字段、主键与关系如何对应数据库。帖子属于一个用户,用户拥有多篇帖子;应用里的对象关系,最终需要数据库中的关联字段来表达。知道包装器叫什么还不够,理解底层表结构会让调试更有方向。
随后是 migration:准备阶段创建结构,回退阶段描述怎样撤销。示例为了清楚,用的是建表与删表的简单对应;真实系统已有用户数据时,回退不能照抄为直接删除。迁移记录则让系统知道哪些变化已经执行,避免每次启动都从头猜数据库状态。
Docker Compose 在这里帮助启动本地数据库,并集中描述镜像、数据卷、环境变量与端口。应用的连接参数要与数据库环境一致,容器中的端口也不是自动等于宿主机端口。Kevin 用应用包作类比介绍镜像的可重复性,实际仍需要相应容器运行环境,不能理解为任何机器双击一个文件就完成所有部署。
路由把 URL 与 HTTP 方法分派到不同处理函数;控制器再根据请求读写模型。注册好后,可以列出路由,检查接口是否进入了应用。文档注释配合 DocC 能把接口意图交给协作者,但文档是否准确仍取决于维护,不会仅因为自动生成就与行为永远一致。
测试、身份与部署:示例能跑通,不等于生产已经完备
1:45:29 开始,Kevin 用中间件演示请求如何携带用户上下文。他特意说明,把请求头里的用户 ID 直接当身份只是教学简化,不能用于真实认证。有人知道另一个人的 ID,并不能证明他有权代表那个人发帖。
DTO 则把网络输入输出与数据库模型分开。客户端需要什么字段、哪些字段不应暴露、输入是否完整,不一定与存储对象一致。测试中,先创建用户,再以该用户创建帖子,并验证返回内容和关联关系。这比只检查“服务器没报错”更接近业务要求。
他还强调失败路径:密码或令牌错误时必须拒绝,而不只是成功时能创建记录。这些测试可以在后续改动时提供稳定反馈,但仍需覆盖权限、输入和异常条件;几条成功案例不是整个 API 的完备证明。
部署部分把构建与运行分开,先在带有 Swift 工具链的环境编译,再把产物放进更精简的运行镜像。Compose 负责组织应用与数据库,GitHub Actions 根据版本标签构建并推送镜像,服务器再使用对应产物。这里能借鉴的是把重复步骤写成可追踪流程,不是“镜像生成了就已经高可用”。
一个容易混淆的细节是依赖启动顺序。启动数据库容器,并不表示数据库已经准备接受连接;实际服务还需处理就绪检查与连接失败。Docker 的官方说明明确区分了运行与就绪。 同样,监听 0.0.0.0 表示监听相应环境中的所有接口,不是“只绑定本机”的安全保证。端口暴露和生产配置仍需要单独管理。
面对缺少 SDK 的第三方服务,Kevin 提出让另一种语言负责它擅长的部分,再通过明确接口连接。可以是独立服务,也可以是托管函数;这种拆分解决兼容问题,也增加网络与运维边界。末尾他谈跨不同故障范围部署实例,强调两份进程不一定能抵抗同一台机器或同一区域故障。不过多开实例也不能独自解决数据库、流量切换与其他共同依赖的问题。
Vision Pro 的入口:窗口、三维内容与沉浸空间
2:02:17 开始,Eric 从开发者课程介绍 Apple Vision Pro。他把窗口、体积与沉浸空间作为理解界面的入口,再连接到 SwiftUI、RealityKit、ARKit 和内容创作工具。已有二维界面可以成为起点,三维模型与空间交互则带来新的表达方式。
示例让人看到怎样把模型放进界面、怎样利用系统提供的跟踪与交互,以及 Reality Composer Pro 如何帮助组织内容。Unity 的支持也让已有项目多一种路线。但“有熟悉的工具”不等于整个产品可以无缝搬过去:输入、布局、舒适度、性能与用户任务都需要重新考虑。SwiftUI 很重要,visionOS 也并非只能使用 SwiftUI;Apple 当年的 UIKit 课程直接展示了另一条接入路径。
眼与手的组合让交互不再完全依赖手持控制器,这也是嘉宾兴奋的地方。不过系统理解视线,不等于应用能任意读取眼动原始数据。Apple 在2023 年发布资料中明确说明,用户看向何处保持私密,眼动信息不分享给第三方应用或网站。讨论可用交互时,需要把系统行为与开发者权限分开。
Eric 将这些入口联系到娱乐、医疗展示与专业场景,也使用其他头戴设备和一段战术题材影像作类比。这部分说明的是他对信息叠加、共享空间与协作的兴趣,不能把影像中的效果当作 Vision Pro 的实测能力,也不能据此确认相关项目的部署规模或具体用途。
自己的三维项目,怎样接上一个新平台
2:17:38 起,Eric 展示 Pixel 3D 的方向。过去先采集物体图像,再在 Mac 上重建模型;2023 年 Object Capture 把一部分端到端流程带到支持的 iOS 设备,让采集与重建可以在同一设备进行。他希望据此改进产品,并把生成的内容用于新的空间设备。
这里的流程仍然是采集图像与模型重建,不等于把任意场景实时转换成高精度模型。Apple 的当年课程还明确了设备与细节级别等条件;iOS 重建当时支持 reduced 级别,需要其他细节级别时可以转到 Mac。Eric 也坦言自己尚未比较新流程的实际效果,因此对手机、Mac 或未来头戴设备效果相同的推断不能提前成立。
他接着介绍定位、地图构建与多设备协同的研究方向,以及太阳系和轨道可视化项目。前者强调不同设备获取的信息怎样形成可共享空间,后者强调把已有三维内容转成更容易观察与操作的体验。这些是个人项目介绍与后续计划,不意味着公开发布的 Vision Pro 已具备他设想的整套系统。现场略过的航天地点、年份与外部演示背景,也不影响理解其核心想法:新平台可能给已有内容一个新的观看与交互方式。
问答一:语言在进步,工具和生态能不能跟上
2:23:31 的问答先回到学生作品。学生嘉宾分享一个实际阻碍:当时创建的 Playground 包默认最低系统版本较旧,导致新 API 无法使用,而界面里又不容易找到修改位置。他最终检查包配置解决。值得记住的是项目配置和 API 可用性之间的关系,不是把当年预览工具的操作细节当作永久教程。
接下来的语言讨论没有统一答案。SwiftUI 分享嘉宾认为 Swift 吸收了许多现代语言思路,也感受到平台框架需求与语言演进节奏的相互影响;关于 Apple 内部如何安排保密与提案,是他的观察与判断。Eric 谈自己大量使用 Swift 的经历,同时仍在测试 SwiftUI 对产品需求的适应性。
Kevin 更关心跨平台复用,希望自己已有的逻辑能在更多环境运行,因而提到 WebAssembly。他也直接抱怨 Xcode 的补全与响应问题,担心语言特性不断增加后,初学者理解成本也随之上升。学生嘉宾则希望服务端和跨平台生态更丰富。另一条意见是尝试 Unity、C# 等不同工具,不必只围绕一种语言寻找全部答案。
这些期待共同指向一个很实际的标准:语言增加了多少能力之外,开发者完成任务是否更顺畅?兼容、文档、调试和社区资源,决定了新语法能不能进入持续维护的产品。
问答二:用户为什么要一次又一次戴上设备
2:35:16 开始,最后的圆桌把焦点从技术转到内容和商业。Kevin 回忆自己使用过多种 VR 设备:第一次的新鲜感很强,联网运动也曾让他持续使用,但后来穿戴、出汗和进入设备的步骤逐渐成为阻力。这个个人经历提出了一个尖锐问题:如果手机、电脑或现实活动已经足够方便,新的体验究竟补上了什么?
他并不是否认所有空间应用,而是区分第一次演示的吸引力与长期使用的动力。所谓必须提高“十倍体验”,在现场是帮助思考切换成本的说法,不是经验证的通用定律。开发者还要面对装机量、定价与投入回报,当时这些都没有成熟答案。
Eric 提出专业项目、办公与机构采购的路径:在一个已有预算、目标清楚的场景里,设备成本的权重可能不同。其他嘉宾则追问,虚拟多屏究竟比多买几块显示器带来什么额外价值。SwiftUI 分享嘉宾认为不必一开始就追求复杂三维,适当增加空间表达,也许就能帮助理解数据与关系。
学生嘉宾设想把信息做成空间看板,承认它也可能首先满足好奇心,而非不可替代的需求。随后讨论又回到真实社交与现实体验:有人希望更自然地融入环境,有人反而期待一种现实里无法得到的体验。教育因此成为最后的重要方向,生物、物理或化学的空间演示可能帮助理解,但价格也可能成为新的门槛。
圆桌没有把设备的未来归结为“只要便宜就一定成功”,也没有用某个人的厌倦否定所有应用。它留下的是一组需要产品来回答的问题:谁会持续使用、在哪个情境使用、相对现有方法多得到什么,以及为此承担多少成本。这与开场的学生项目形成了呼应——再新的技术,最终仍要服务于一个讲得清楚、也能被人实际体验的问题。
