What's new in Xcode
Developer Tools 进阶 40m

Xcode 新特性

What's new in Xcode

2025年6月9日

在 Apple 官方观看视频

一句话判断

Xcode 26 把 Apple Intelligence 直接嵌入了 IDE 工具链——真正改变日常开发节奏的不是 AI 本身,而是 #playground 宏让代码验证从”事件”变成了”习惯”。

这场 Session 讲了什么

Xcode 26 的 Coding Assistant 不是简单的代码补全。它读取项目上下文——文件依赖、类型定义、项目结构——然后在这个基础上做解释、生成和修复。选中一段代码,Coding Tools 弹出菜单直接提供解释、文档生成、甚至自动创建 playground。Fix-It 弹窗新增的 Generate 按钮更实用:遇到弃用警告,点一下就自动迁移到新 API,连迁移原因都给你解释清楚。这比 Copilot 的通用补全强在它知道你的代码长什么样。

#playground 宏是这版最被低估的特性。在任何 Swift 源文件里写 #playground { },Canvas 标签页实时显示执行结果。你不再需要创建单独的 Playground 文件、切换窗口、等待编译——验证一段代码的假设变成了随手的事。编码助手还能为任意符号自动生成 playground,帮你在几秒内理解一个陌生函数的行为。

Swift 并发调试也有实质进展。现在可以步入/步出 await 调用,跟踪任务在哪个线程上执行。异步代码调试终于不再是猜谜游戏。

值得深挖的点

Coding Assistant 的”上下文感知”到底深到哪一层

大多数 AI 编码工具的上下文理解停留在当前文件——给它一个函数,它能基于函数体和类型标注生成代码。Xcode 26 的 Coding Assistant 走得更远:它感知项目图。你的类型定义、依赖关系、甚至项目结构,都在它的理解范围内。这意味着当它生成代码时,它不只是语法正确,而是会在你已有的抽象上构建——用你的网络层、你的数据模型、你的错误处理方式。

这改变了 Fix-It 的工作流。旧方案里,弃用警告意味着你要查文档、理解新 API 的行为差异、手动改代码。现在 Generate 按钮让编码助手直接读旧代码、查新 API 签名、生成迁移后版本并解释变更原因。开发者从”执行者”变成了”审核者”。

但边界也很清楚。宏展开后的代码、运行时动态生成的内容、通过 SPM 依赖引入的第三方库——这些它能理解到什么程度?从目前的描述看,它能读取依赖的类型签名和文档,但未必能深入实现细节。项目上下文是有层次的,AI 的理解深度取决于它如何索引这些层次。这不是 Xcode 26 能一步到位的问题,但方向是对的:IDE 级别的 AI 不应该只是通用 LLM 加一个编辑器。

playground 宏:为什么它比你想的更重要

表面上看,#playground 是个语法糖——在源文件里嵌入可执行代码,在旁边看结果。但它改变的是验证行为的频率。以前你想到一个假设,需要创建 Playground 文件、切窗口、等编译、再切回来。这个摩擦力足以阻止你在写代码时随手验证。现在 #playground 就在你正在编辑的文件里,结果在 Canvas 里实时出现,验证成本从 30 秒变成了 2 秒。

这个变化对代码质量的影响是渐进的。你会更频繁地验证假设,更早地发现问题。对陌生 API 的探索从”猜着用”变成了”试了再用”。编码助手可以为任意符号自动生成 playground,这对理解第三方库或接手旧项目特别有用。

#Preview 的区别很关键:Preview 专注于 UI 视图的实时预览,#playground 是通用的代码执行环境,验证任何 Swift 代码逻辑。两者互补,不替代。一个实际问题是:#playground 在 release 构建中是否会被完全剥离?如果它和 #Preview 的实现机制类似,答案应该是肯定的,但这值得在 Xcode 26 正式发布后验证。

代码片段

// 用 #playground 在源文件中即时验证数据转换逻辑
// 场景:写了一个 JSON 解码扩展,想确认输出格式对不对
extension Data {
    func decode<T: Decodable>(_ type: T.Type) -> T? {
        try? JSONDecoder().decode(type, from: self)
    }
}

#playground {
    let json = #"{"name": "Alice", "age": 30}"#.data(using: .utf8)!
    let user = json.decode(User.self)
    print(user?.name)  // Canvas 里直接看到 "Alice"
}
// 坑:#playground 的代码和源文件共享作用域,定义的变量可能会污染后续代码
// 通过 Coding Assistant 的 Generate 按钮修复弃用警告
// 场景:项目中有大量 onChange 用旧 API 写法
// 迁移前:
.onChange(of: searchText) { newValue in
    updateResults()
}
// 点击 Issue 导航器中的 Generate 按钮后,自动变为:
.onChange(of: searchText) { oldValue, newValue in
    updateResults()
}
// 坑:自动迁移只处理语法,不处理语义——如果旧代码依赖"仅在新值时触发",
// 新 API 的 oldValue 参数需要你手动加判断
// 异步代码调试:跟踪任务线程切换
// 场景:并发下载多张图片,想知道每张图在哪个线程上处理
await withTaskGroup(of: UIImage?.self) { group in
    for url in imageURLs {
        group.addTask {
            let data = try? await URLSession.shared.data(from: url).0
            return data.flatMap(UIImage.init)  // 在这里打断点,现在可以步出 await 了
        }
    }
}
// 坑:步入 await 调用会让调试器停在系统框架内部,信息量很大,
// 建议配合 Instruments 的 SwiftUI 模板一起用,别只靠断点

最佳实践

建议先让团队启用 Coding Assistant。在 Intelligence 设置里配好模型,优先用 Apple 的默认模型——它对 Swift/SwiftUI 的理解比通用模型准。然后用 Generate 按钮批量修复项目里的弃用警告,特别是 onChange、onSubmit 这些高频 API 的迁移。这是最低成本、最高收益的第一步。

#playground 的迁移更简单:把散落在各处的 Playground 文件里有价值的验证逻辑,搬到对应源文件的 #playground 块里。不需要一次性全搬,下次打开某个 Playground 文件时顺手做就行。

性能工具优先级较低。SwiftUI body 超过 1ms 是个好指标,值得在 Instruments 里看看,但不要为了优化而优化。先让 AI 辅助和 playground 渗透到日常流程里,再回来做性能调优。Icon Composer 的迁移可以排到下一个设计周期——除非正在做 Liquid Glass 适配。

还有什么值得关注

  • Type-safe String Catalog 访问让本地化 key 拥有编译时检查和代码补全,不再靠字符串拼接猜 key 名
  • Multiple Words Search 在 Find 导航器中支持多词搜索并按关键词聚类结果,在大型项目里找代码的效率提升明显
  • Voice Control 对 Swift 语法的理解增强,用语音写代码的纠错成本降低了一个量级
Xcode AI 调试 性能 Icon Composer