WWDC Quick Look 💓 By SwiftGGTeam
What’s new in Xcode 26

What’s new in Xcode 26

观看原视频

Highlight

Xcode 26 把下载体积缩小 24%、workspace 加载提速 40%、复杂表达式输入延迟降低 50%,并通过 #Playground 宏让任意 Swift 文件都能内联跑实验代码。

核心内容

打开一个大型 Swift 工程,敲一个稍微复杂的表达式,光标后面要等半秒才出字符;切换 workspace 要等 Xcode 把所有索引重新加载一遍;下载一个完整 Xcode 包要占掉几十 GB 磁盘——这是过去几年开发者抱怨最多的几个点。Landmarks 这种带 SwiftUI 预览的项目里,调试一段从字符串解析坐标的正则、看一眼某个 struct 的字段,往往要先跑起整个 app,再点到对应页面,效率很低。

Xcode 26 的回应是把”工具更轻”和”反馈更快”做成了同一件事。下载体积缩小 24%,比 2014 年的 Xcode 6 还小:Simulator runtime 默认不再带 Intel 支持,Metal toolchain 改为按需下载(00:52)。workspace 加载提速 40%,某些复杂表达式的输入延迟降低 50%(01:20)。在编辑层面,新的 #Playground 宏让任何文件都能内联跑一段实验代码,结果实时显示在 canvas tab 中——演讲里 Eliza 用它发现”大峡谷被定位到中国”的 bug,整个过程没有重启 app(05:12)。再加上 Coding Assistant、Voice Control Swift 模式、Icon Composer、String Catalog 的类型安全 Swift 符号,Xcode 26 把”想到什么立刻能验证”这条回路缩得更短。

详细内容

#Playground 宏来自新引入的 Playgrounds 模块,可以放在任何 Swift 文件里。它和 SwiftUI Preview 一样属于”边写边看”的工具,但作用对象是任意表达式而不是 View(04:47)。最小用法只需要两步:导入模块、写一个块。

import Playgrounds

#Playground {
  let landmark = Landmark.exampleData.first
  let region = landmark?.coordinateRegion
}

关键点:

  • import Playgrounds#Playground 宏带入当前文件,宏本身随 Xcode 26 提供。
  • #Playground { ... } 在编译期展开,块内每个表达式都会作为独立条目显示在 canvas tab 里,包括属性值与 Quick Look 可视化。
  • Landmark.exampleData.first 这类访问真实工程类型的写法直接生效,不需要为 playground 搭单独的 target——它就在源文件里。
  • 修改块内代码,canvas 自动重跑相关表达式,省掉”改 → 重启 app → 复现 → 观察”的循环。

Eliza 用它定位坐标 bug 时的关键代码是一段正则。原始版本只匹配可选的小数部分,没考虑符号位,把负经度解析成了正数(06:33):

func scanForFloatingPointNumbers() -> [Regex<Substring>.Match] {
    return self.matches(of: /[0-9]*[.][0-9]+/)
}

关键点:

  • Regex<Substring>.Match 是 Swift 正则的新返回类型,每个匹配都带有原字符串里的 range,canvas 能直接把命中范围高亮出来。
  • self.matches(of:)String 的扩展方法,配合正则字面量 /.../ 写法,免去手工构造 NSRegularExpression
  • 这段代码的缺陷在 canvas 中一眼可见:演示里输入 "lon: -113.16096, lat: 36.21904" 后,命中范围里没有包含 -06:49)。

修正版本只在小数部分前面加上可选的 [+-]?07:33):

func scanForFloatingPointNumbers() -> [Regex<Substring>.Match] {
    return self.matches(of: /[+-]?[0-9]*[.][0-9]+/)
}

关键点:

  • [+-]? 让符号位变为可选项,从而正确捕获负数。
  • 由于 canvas 在改动后立即重跑,“改正则 → 看 range 是否包含负号”的反馈以秒为单位完成,无需重新启动 app。
  • 切回第一个 playground,Grand Canyon 的坐标已经回到正确位置,整个调试链路都在源代码视图里完成。

性能与测试方面,UI 测试新增了 XCTHitchMetric 用于度量滚动卡顿(34:40):

func testScrollingAnimationPerformance() throws {
    let measureOptions = XCTMeasureOptions()
    measureOptions.invocationOptions = .manuallyStop

    let app = XCUIApplication()
    app.launch()
    let scrollView = app.scrollViews.firstMatch

    measure(metrics: [XCTHitchMetric(application: app)], options: measureOptions) {
        scrollView.swipeUp(velocity: .fast)
        stopMeasuring()
        scrollView.swipeDown(velocity: .fast)
    }
}

关键点:

  • XCTHitchMetric(application:) 直接把目标 app 作为参数,度量它在 measure 块里的 hitch(动画掉帧)总时长。
  • XCTMeasureOptions().invocationOptions = .manuallyStop 允许手动 stopMeasuring(),从而把”上滑”算入度量、把”下滑”排除在外,只测真正关心的滚动方向。
  • scrollView.swipeUp(velocity: .fast) 用最快速度触发滚动,更容易暴露动画性能问题。
  • 这个 metric 适合放进性能基线,回归时一旦 hitch 时长上升就能在 Test Report 里看到。

其余值得记住的细节:编辑器 tab 的行为改成 Safari 风格,可以 pin 到固定文件(01:52);多词搜索(Multiple Words search)用搜索引擎技术按邻近度查找跨行词簇(02:21);Voice Control 加入 Swift 模式,支持按自然朗读方式写代码(03:22);Icon Composer 作为独立 app 与 Xcode 26 一起发布,用一份文件输出多平台、多模式的 app icon(08:15);String Catalog 现在能生成类型安全的 Swift 符号,并基于 on-device 模型自动产生翻译注释(09:48);Coding Assistant 接入 ChatGPT、Anthropic Claude(Opus、Sonnet)以及本地 Ollama / LM Studio,能感知项目上下文并直接修改代码(10:38);调试器跟随 Swift Concurrency 的线程切换,Instruments 在 M4+ 设备上提供 Processor Trace,并新增 Power Profiler。

核心启发

  • 做什么:把”看一眼数据是什么样”这类需求从临时 print 改写成 #Playground 块。

    • 为什么值得做:playground 块就在源文件里,canvas 实时更新,调试一个 struct 的字段、一段正则、一段日期格式化逻辑不再需要跑整个 app。
    • 怎么开始:在团队规范里加一条”非 UI 的临时验证一律用 #Playground”,并把常用样例数据放进静态属性(如 Landmark.exampleData),保证 playground 能直接拿到代表性输入。
  • 做什么:把性能回归测试从”主观感受卡不卡”换成 XCTHitchMetric 基线。

    • 为什么值得做:滚动卡顿是用户最敏感的体验之一,但人眼很容易适应;用 metric 把它量化后才有 PR 级别的拦截能力。
    • 怎么开始:先为 app 里最长、最复杂的两三个列表写 hitch 测试,记录当前数值作为 baseline,然后在 CI 里设阈值,一旦 hitch 时长上涨就阻断合并。
  • 做什么:把所有界面字符串从硬编码改造成 String Catalog 里的类型安全符号。

    • 为什么值得做:Xcode 26 会基于 catalog 条目生成 Swift 符号,编译期检查拼写错误,自动补全可用 key;on-device 模型自动写注释,减少和翻译沟通的成本。
    • 怎么开始:选一个流程完整的小模块(如设置页)先迁移,把 Text("Save") 改成 catalog 生成的符号;跑通一遍翻译流,再推广到其他模块。
  • 做什么:在大项目里默认开启 Coding Assistant,但关闭”自动应用”选项。

    • 为什么值得做:模型回答能直接读到项目上下文,对探索陌生代码库非常有用,但盲目接受它的修改会引入难以察觉的回归。
    • 怎么开始:先用它解答”这个功能在哪个文件”这类纯检索问题,逐步扩展到生成 playground、写测试,最后再考虑由它直接改代码。

关联 Session

评论

GitHub Issues · utterances