WWDC Quick Look 💓 By SwiftGGTeam
Triage TestFlight crashes in Xcode Organizer

Triage TestFlight crashes in Xcode Organizer

观看原视频

Highlight

Xcode 13 把 TestFlight 崩溃快速投递、测试员反馈、分布图、崩溃分享、Terminations Organizer 和 MetricKit 更快诊断投递整合进开发者排查流程,帮助团队更快定位线上和测试版崩溃。

核心内容

一个常见的崩溃排查流程很绕。

测试员在 TestFlight 里遇到崩溃,写了一段反馈。开发者要去 App Store Connect 看反馈,下载 crash log,再回到 Xcode 分析调用栈。如果问题只在特定网络、设备或版本上出现,单独的 crash log 往往不够。

Xcode 13 改了这条链路。TestFlight 构建发生崩溃后,Organizer 会在片刻后收到崩溃。Crashes Organizer 还把最近一天的 TestFlight 崩溃、按小时统计的图表、一年历史、版本和产品过滤器放在同一个界面里。

这让排查从“先收集材料”变成“直接看上下文”。你可以先过滤到 App Clip、watch app 或 extension,再看它影响了多少设备、从哪个版本开始出现、是否已经进入 App Store 版本。

TestFlight 反馈进入 Xcode

过去,测试员的文字反馈和崩溃调用栈分散在不同地方。Xcode 13 新增 Feedback Inspector(反馈检查器),把命中同一个崩溃的测试员反馈放在 crash report 旁边。

Session 里的 Fruta 示例很具体。开发者看到一个 App Clip 崩溃,调用栈显示它发生在后台线程的 favorites 同步逻辑里。单看代码,很难知道触发条件。Feedback Inspector 显示测试员当时在隧道里,使用蜂窝网络,按下 favorite 按钮后几秒崩溃。

这些线索串起来,问题就清楚了:网络质量差导致后端同步超过 10 秒,代码用 fatalError 主动崩溃。修复方向也变成处理超时,开发者不必继续猜测复现步骤。

崩溃可以直接分享给团队

团队协作时,另一个常见麻烦是“你看一下这个崩溃”。对方给一张截图或一段描述,接收者还要自己在 Organizer 里搜索。

Xcode 13 给 Crashes Organizer 加了 Share 按钮。分享出来的链接可以指向一个具体崩溃。接收者点击链接后,Organizer 会下载并聚焦到该崩溃,不需要重新筛选。

Terminations Organizer 补上另一类退出

Crashes Organizer 关注编程错误导致的崩溃。应用进程还有另一类退出:启动超时、达到系统内存限制、后台被系统终止。

Xcode 13 新增 Terminations Organizer(终止管理器),按原因展示终止趋势,并支持和旧版本对比。它帮助开发者判断某类终止是否是新版本引入的回归,也能区分终止发生在后台还是应用前台。

MetricKit 更快交付崩溃诊断

MetricKit(指标框架)可以在应用代码里接收诊断数据。Xcode 13 中,crash diagnostics 不再每天聚合投递一次,而是在应用下次启动时投递。MetricKit 也开始支持 macOS。

这适合做自己的崩溃后台。你可以在应用启动后注册订阅者,收到 MXDiagnosticPayload 后读取 crashDiagnostics,再把诊断数据接入已有分析系统。

详细内容

TestFlight 崩溃快速投递和过滤

02:17)Xcode 13 会在 TestFlight 构建崩溃后片刻把 crash 送到 Organizer。Crashes Organizer 可以查看最近一天的 TestFlight 崩溃,并用小时图显示所选崩溃发生的时间分布。

Session 还提到,一年崩溃历史现在可用。开发者可以按时间范围过滤,查看过去一年内发生过的崩溃。检查器里的图表会按月显示崩溃的普遍程度。

关键入口:

Window → Organizer → Crashes
Filter: Time Period → Last Day / Last Two Weeks / Last Year
Filter: Versions and Builds → All Versions and Builds / Individual Release
Filter: Products → iOS App / App Clip / watch app / app extensions
Distribution: Versions / TestFlight / App Store

关键点:

  • Window → Organizer → Crashes 打开 Xcode 的 Crashes Organizer。
  • Time Period 用来收窄时间范围,Session 中展示了最近一天、最近两周和一年历史。
  • Versions and Builds 用来判断崩溃从哪个版本开始出现,或是否只影响某个构建。
  • Products 用来过滤 App Clip、watch app、extension 等随应用发布的产品。
  • Distribution 用来查看同一个崩溃在版本、TestFlight 和 App Store 之间的分布。

06:13)演示里的 Fruta 应用先打开 Organizer,再用产品过滤器选择 App Clip。列表中的崩溃会显示 badge,标明它来自 App Clip、watch app 或 extension。开发者因此能先确认受影响的应用区域。

关键入口:

Crashes Organizer
  Products Filter → App Clip
  Crashes List → Top Crash
  Inspector Graph → First appeared in version 2.0
  Release Filter → TestFlight and App Store

关键点:

  • Products Filter → App Clip 只显示 App Clip 的崩溃。
  • Top Crash 显示最近两周和最近一天影响的设备数。
  • Inspector Graph 显示该崩溃最早出现的版本。
  • Release Filter 帮助确认问题是否已经影响 App Store 用户。

Feedback Inspector 把复现线索放到崩溃旁边

04:44)Xcode 13 把 TestFlight Crash Feedback(TestFlight 崩溃反馈)带进 Crashes Organizer。开发者仍然可以在 App Store Connect 下载原始反馈和 crash log,也可以用新的 Open in Xcode 按钮直接打开关联崩溃。

关键入口:

App Store Connect → TestFlight Feedback → Open in Xcode
Xcode Organizer → Crashes → Feedback Inspector
Feedback Report → version, build, device model, battery level, available disk space, tester comment

关键点:

  • Open in Xcode 从 App Store Connect 跳转到 Organizer 中的关联崩溃。
  • Feedback Inspector 显示命中所选崩溃的所有测试员反馈。
  • versionbuild 说明测试员安装的具体版本。
  • device modelbattery levelavailable disk space 提供设备状态。
  • tester comment 是复现条件的直接来源,Session 示例里的关键线索是隧道、蜂窝网络和 favorite 按钮。

09:24)Fruta 示例中,反馈报告显示测试员在蜂窝网络下穿过隧道。结合调用栈里的后台同步逻辑,开发者推断网络质量差会让后端同步超过 10 秒,触发代码里的崩溃。

关键排查路径:

Feedback: "I was going through a tunnel and I hit the favorite button. A few seconds later, it crashed."
Backtrace: background thread, syncing favorites
Code path: save favorite to disk → update backend → wait with 10-second timeout → fatal error
Fix direction: increase timeout and call completion handler on timeout

关键点:

  • 测试员反馈给出“隧道”和“蜂窝网络”两个环境条件。
  • backtrace 显示崩溃发生在后台线程,位置在 favorites 同步。
  • 代码路径包含磁盘保存、后端更新和 dispatch group 等待。
  • 10 秒超时触发崩溃,修复思路是把超时当作可处理结果。

Open in Project 和 Share 缩短团队协作

10:19)当开发者准备修复崩溃,可以用 Open in Project 按钮打开工程。Xcode 会在 Debug Navigator 显示 backtrace,并在编辑器里高亮崩溃代码行。

关键入口:

Crashes Organizer → Selected Crash → Open in Project
Xcode Project → Debug Navigator → Backtrace
Editor → Highlighted crashing line

关键点:

  • Open in Project 从 Organizer 进入对应 Xcode 工程。
  • Debug Navigator 显示 crash backtrace。
  • 编辑器直接高亮崩溃行,减少手动定位文件和行号的步骤。

04:01)Xcode 13 还可以从 Organizer 直接分享 crash report。工具栏里的 Share 按钮能把崩溃链接发给团队成员,或加入待办列表。

关键入口:

Crashes Organizer → Toolbar → Share
Shared Link → Organizer downloads and focuses on the issue
Resolved Crash → Friendly Name

关键点:

  • Share 生成指向具体崩溃的链接。
  • 团队成员打开链接后,Organizer 会聚焦到该崩溃。
  • 已解决的崩溃可以被标记 resolved,并设置更容易识别的名称。

Terminations Organizer 关注非 crash 退出

12:59)Terminations Organizer 展示应用终止趋势。Session 明确区分了 crashes 和 terminations:前者来自编程失败,后者可能来自启动超时、系统内存限制等原因。

关键入口:

Xcode Organizer → Terminations
Termination Categories:
  - Timing out on launch
  - Hitting the system memory limit
Compare: current version vs previous versions
Context: background vs onscreen

关键点:

  • Terminations 是 Organizer 中的新视图。
  • Timing out on launch 表示应用启动耗时超过系统允许范围。
  • Hitting the system memory limit 表示进程达到系统内存限制。
  • Compare 用来找出新版本相对旧版本的终止回归。
  • background vs onscreen 帮助判断终止对用户体验的直接影响。

MetricKit 在下次启动投递 crash diagnostics

13:56)MetricKit 可以在应用代码里收集 crash logs。Xcode 13 的变化是 crash diagnostics 不再每天聚合一次投递,而是在应用下次启动时投递。Session 还宣布 MetricKit 支持 macOS。

官方代码片段如下。

//  Capture crash logs in your code

import MetricKit

class Subscriber: NSObject {
    override init() {
        super.init()
        MXMetricManager.shared.add(self)
    }

    deinit {
        MXMetricManager.shared.remove(self)
    }
}

extension Subscriber: MXMetricManagerSubscriber {
    func didReceive(_ payloads: [MXDiagnosticPayload]) {
        payloads.forEach {
            if let crashDiagnostics = $0.crashDiagnostics {
                // Begin analyzing crash diagnostic payload.
            }
        }
    }
}

关键点:

  • import MetricKit 引入 MetricKit 框架。
  • Subscriber: NSObject 定义一个 Objective-C 运行时兼容的订阅对象。
  • override init() 在对象创建时注册订阅者。
  • MXMetricManager.shared.add(self) 开始监听 MetricKit payload。
  • deinit 在对象释放时取消订阅。
  • MXMetricManager.shared.remove(self) 防止订阅者继续接收回调。
  • MXMetricManagerSubscriber 是接收 MetricKit payload 的协议。
  • didReceive(_ payloads: [MXDiagnosticPayload]) 在诊断 payload 到达时调用。
  • payloads.forEach 遍历本次收到的所有诊断 payload。
  • $0.crashDiagnostics 读取 crash diagnostics;有值时再进入分析流程。

核心启发

1. 给 TestFlight 崩溃建立每日排查队列

  • 做什么:每天打开 Crashes Organizer,只看最近一天的 TestFlight 崩溃,按影响设备数排序处理。
  • 为什么值得做:Xcode 13 会在 TestFlight 崩溃后片刻投递,最近一天视图和小时图能帮助你快速确认新构建是否引入问题。
  • 怎么开始:从 Window → Organizer → Crashes 进入,设置 Time Period → Last Day,再用版本和产品过滤器定位当前测试构建。

2. 为 App Clip、watch app 和 extension 分开看稳定性

  • 做什么:把主应用、App Clip、watch app、分享扩展的崩溃分别过滤查看。
  • 为什么值得做:Session 中的 crashes list 会用 badge 标出崩溃来源,产品过滤器能直接聚焦某个随应用发布的产品。
  • 怎么开始:在 Crashes Organizer 打开 Products Filter,选择 App Clip、watch app 或目标 extension,记录每个产品的 top crash。

3. 把测试员反馈当作复现步骤来源

  • 做什么:修 TestFlight 崩溃前,先读 Feedback Inspector 里的测试员评论和设备状态。
  • 为什么值得做:Fruta 示例证明,测试员的一句话能解释调用栈背后的环境条件,例如弱网络、设备状态和用户操作。
  • 怎么开始:在崩溃列表中寻找反馈图标,打开 Feedback Inspector,重点看版本、构建、设备型号、电量、可用磁盘空间和评论。

4. 用分享链接减少团队排查成本

  • 做什么:遇到需要同事处理的崩溃,直接从 Organizer 分享崩溃链接。
  • 为什么值得做:接收者打开链接后,Organizer 会下载并聚焦到同一个 crash,避免截图和口头描述带来的歧义。
  • 怎么开始:选中 crash report,点击工具栏 Share,把链接发给负责模块的同事或放入任务系统。

5. 在应用里接入 MetricKit crash diagnostics

  • 做什么:在应用启动路径创建 MetricKit 订阅者,收集 crashDiagnostics 后接入自己的诊断后台。
  • 为什么值得做:Xcode 13 让 crash diagnostics 在下次启动时投递,速度比每天聚合一次更适合快速定位崩溃。
  • 怎么开始:引入 MetricKit,创建实现 MXMetricManagerSubscriber 的对象,用 MXMetricManager.shared.add(self) 注册,在 didReceive(_:) 里读取 MXDiagnosticPayload.crashDiagnostics

关联 Session

评论

GitHub Issues · utterances