Highlight
Xcode 15 的 Playgrounds 支持自动运行、内联结果展示和自定义类型描述,开发者可以在不重建项目的情况下快速原型化新功能,将迭代时间从分钟级降到秒级。
核心内容
你有一个功能想法,但每次修改都要重新编译、启动 App、导航到对应页面才能看到效果。这个循环可能要几分钟,灵感早就凉了。
Xcode Playgrounds 可以打破这个循环。把它加到项目里,直接调用项目中的类型,修改代码后秒级看到结果。
(02:34)演讲者正在开发一个野生动物摄影 App,想给 checklist 增加筛选功能。列表里有 2000 多种鸟类,全部显示没有成就感。他需要在 birdsToShow 计算属性里加过滤逻辑。
直接在项目里新建 Playground(File > New > Playground),选择 Blank。项目中的 Playground 默认启用两个设置:
- Build Active Scheme:每次执行前自动构建活跃 scheme
- Import App Types:自动导入 app target 模块
这意味着 Playground 里可以直接使用项目中定义的 BirdProvider、Bird 等类型,不需要手动 import。
(03:15)把运行模式切换到 “Automatically run”,停止输入后 Playground 自动执行。现在可以开始实验了。
内联结果与类型探索
(04:05)声明一个 BirdProvider 实例:
let birdProvider = BirdProvider(region: .northAmerica)
Xcode 15 右侧结果栏显示这行代码的输出。点击内联结果切换按钮,可以看到详细结构:
birds数组region枚举值
每行还有类型信息标签,tooltip 显示类型的来源模块。展开数组时,Xcode 15 会高亮产生该结果的源代码,方便对应。
(05:45)默认情况下,自定义类型 Bird 的数组元素只显示索引号。让 Bird 遵循 CustomStringConvertible:
extension Bird: CustomStringConvertible {
public var description: String {
return "\(commonName) (\(scientificName))"
}
}
关键点:
description返回常见名和科学名的组合- 这个扩展加在定义
Bird的源文件中,debugger 也能受益 - 遵循后,Playground 结果栏直接显示鸟的名称,不需要展开
(07:53)如果想在点击行时显示鸟的相片,用 CustomPlaygroundDisplayConvertible:
extension Bird: CustomPlaygroundDisplayConvertible {
public var playgroundDescription: Any {
return photo as Any
}
}
关键点:
playgroundDescription只在 Playground 环境中生效- 显式转成
Any避免编译器警告 optional 信息丢失 - 返回
nil时,Playground 会回退到默认展示 - Xcode 15 用分屏视图同时显示对象结构和预览
过滤与验证 UI
(09:35)先过滤出还没有照片的鸟:
let birdsToFind = birdProvider.birds.filter { $0.photo == nil }
结果还有 1800 多只。再按科过滤,只看猫头鹰:
let owlsToFind = birdsToFind.filter { $0.family == .owls }
只剩 5 只,范围合理了。
(11:15)验证自定义 ChecklistView:
let checklist = ChecklistView()
for bird in owlsToFind {
checklist.add(bird)
}
Xcode 15 的 Value History 模式用分屏视图展示每次循环迭代后的 UI 状态。演讲者发现表头在只有一只鸟时仍然显示复数 “birds”。
(12:16)在 String Catalog 里给这个词添加复数变体(Vary By Plural),修改单数形式为 “bird”。回到 Playground,表头正确显示单复数形式。
集成外部依赖
(14:27)演讲者想集成 BirdSightings 包来获取最近的观鸟记录。这个包自带文档 Playground,展示了 API 用法:
let barnOwlCode = "BNOW"
let centralParkLocation = CLLocationCoordinate2D(latitude: 40.785091, longitude: -73.968285)
let sightingsProvider = SightingsProvider()
sightingsProvider.fetchSightings(of: barnOwlCode, around: centralParkLocation)
在自己的 Playground 里实验:
import CoreLocation
import BirdSightings
let bird = owlsToFind.first!
let appleParkLocation = CLLocationCoordinate2D(latitude: 37.3348655, longitude: -122.0089409)
let sightingsProvider = SightingsProvider()
let sightings = sightingsProvider.fetchSightings(of: bird.speciesCode, around: appleParkLocation)
let mostRecentSighting = sightings.first
let sightingMapView = SightingMapView(sighting: mostRecentSighting)
(18:55)用 Live View 查看地图效果:
import PlaygroundSupport
PlaygroundPage.current.liveView = sightingMapView
发现地图定位到了错误的位置。用 Xcode 15 改进的 CLLocationCoordinate2D 预览检查坐标,发现经度少了负号。修正后地图正确显示 Apple Park 附近。
(22:20)把验证过的代码搬回项目:
func sightingToShow(for bird: Bird) -> Sighting? {
let sightingsProvider = SightingsProvider()
let sightings = sightingsProvider.fetchSightings(of: bird.speciesCode, around: lastCurrentLocation)
let mostRecentSighting = sightings.first
return mostRecentSighting
}
详细内容
Playground 执行模式
Xcode 15 提供两种执行模式:
- Automatically run:停止输入后自动执行,适合快速实验
- Manually run:手动控制执行时机,适合包含网络请求等耗时操作的情况
切换方式:长按底部运行按钮,从菜单选择。
多表达式行的新控件
(09:48)当一行有多个表达式时,Xcode 15 显示新的侧边栏注释。点击控件可以看到每个表达式的独立结果。悬停在内联结果切换按钮上时,高亮对应的源代码范围。
从 Playground 到项目的代码迁移
Playground 里验证过的代码可以直接复制到项目中。需要注意:
- Playground 里可以用
!强制解包,项目代码需要 proper error handling - 网络请求在 Playground 里手动执行,项目里要考虑异步和 loading 状态
- Playground 的 Sources 目录里的扩展只在 Playground 内生效
核心启发
-
做什么:给项目加一个 “Scratch” Playground,专门用来实验新算法和 API
-
为什么值得做:不用重建项目、不用写临时测试代码,秒级看到结果。想法验证成本趋近于零
-
怎么开始:File > New > Playground,选择 Blank,确保 Build Active Scheme 和 Import App Types 已勾选
-
做什么:为项目中的核心模型类型实现
CustomStringConvertible -
为什么值得做:Playground 结果栏、debugger、print 都会显示有意义的描述,调试效率大幅提升
-
怎么开始:给最常用的 3-5 个模型类型加
description属性,返回业务上有意义的字符串 -
做什么:用 Playground 验证第三方包的 API 再集成到项目
-
为什么值得做:包的文档 Playground 或自己写的实验代码,能快速理解 API 的输入输出,避免在项目中反复编译调试
-
怎么开始:import 包到 Playground,用真实参数调用关键 API,观察返回值的结构和内容
-
做什么:用 Live View 预览复杂的自定义 UI 组件
-
为什么值得做:MapView、Chart 等复杂组件在模拟器里查看成本高。Live View 提供全尺寸交互预览
-
怎么开始:创建 UI 组件实例,设置
PlaygroundPage.current.liveView,在 Editor Options 中打开 Live View
关联 Session
- Build programmatic UI with Xcode Previews — 用 #Preview 宏在代码旁实时预览 UI,与 Playgrounds 互补
- What’s new in Xcode 15 — Xcode 15 全面新功能介绍
- Discover String Catalogs — 本地化字符串管理,演讲中提到用 String Catalog 处理复数
评论
GitHub Issues · utterances