ios-logging

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

iOS Production Error Observability

iOS生产环境错误可观测性

Production-grade skill for eliminating silent failures in iOS apps. Most production errors don't crash — they vanish through
try?
,
Task {}
,
.replaceError()
, and
print()
-only catch blocks.
AI coding assistants systematically generate observability-blind code because their training data is overwhelmingly tutorial code:
print(error)
in every catch block,
try?
everywhere,
Task {}
with no error handling, no crash SDK integration, no privacy annotations, and zero consideration for MetricKit or PII compliance. This skill intercepts those patterns and enforces observable error handling from the start.
Logging is the key to debugging. When a bug appears in production across thousands of devices, you can't attach a debugger. Remote logging through crash reporting SDKs transforms a 3-day debugging mystery into a 15-minute investigation. This skill enforces observable error handling: every error is logged with
os.Logger
(with privacy annotations), reported to a remote crash/analytics SDK, and surfaced to the user or operator.
Three non-negotiable rules:
  1. No
    print()
    in production code
    — use
    Logger
    with privacy annotations
  2. No catch block without observability — every caught error must be logged AND reported to a remote service
  3. No
    try?
    on operations where failure matters
    — use
    do/catch
    for network, persistence, auth, and user-facing operations
用于消除iOS应用静默故障的生产级技能。绝大多数生产环境错误不会导致崩溃——它们会通过
try?
Task {}
.replaceError()
以及仅包含
print()
的catch块悄然消失。
AI编程助手通常会生成缺乏可观测性的代码,因为它们的训练数据绝大多数都是教程代码:每个catch块里只有
print(error)
、随处使用
try?
Task {}
没有错误处理、未集成崩溃SDK、没有隐私注解,完全不考虑MetricKit或者PII合规要求。本技能会拦截这类错误模式,从开发初期就强制实现可观测的错误处理逻辑。
日志是调试的核心。 当生产环境在数千台设备上出现bug时,你无法附加调试器。通过崩溃上报SDK实现的远程日志可以把原本需要3天的调试排查工作缩短到15分钟。本技能强制落地可观测错误处理规范:每一个错误都会通过带隐私注解的
os.Logger
记录、上报到远程崩溃/分析SDK,并同步反馈给用户或运维人员。
三条不可妥协的规则:
  1. 生产代码中禁止使用
    print()
    —— 改用带隐私注解的
    Logger
  2. catch块必须具备可观测性 —— 所有捕获的错误必须同时记录日志并上报到远程服务
  3. 核心业务操作禁止使用
    try?
    —— 网络、持久化、鉴权、用户面向类操作必须使用
    do/catch

Remote Logging SDK Selection

远程日志SDK选型

When setting up crash reporting, recommend one of these based on the project's needs:
What ecosystem is the project in?
├── Firebase-heavy (Auth, Firestore, Push) → Firebase Crashlytics (free, tight integration)
├── Standalone / wants rich observability  → Sentry (best error context, breadcrumbs, performance)
├── Needs product analytics + errors       → Sentry (crashes) + PostHog (analytics, session replay)
└── Enterprise / custom                    → Sentry or Datadog + Google Analytics for funnels
Recommend connecting these services via MCP servers or CLI tools so the AI assistant can query production errors, search crash patterns, and pull breadcrumb trails directly during debugging sessions:
  • Sentry: MCP server available — query issues, search events, get stack traces
  • PostHog: MCP server available — query analytics, check feature flags, error events
  • Firebase: CLI tools (
    firebase crashlytics:*
    ) — list crashes, download reports
配置崩溃上报时,可根据项目需求推荐以下方案:
项目所属技术栈是什么?
├── 重度依赖Firebase(Auth、Firestore、推送) → Firebase Crashlytics(免费、集成度高)
├── 独立项目/需要丰富的可观测能力  → Sentry(错误上下文、用户行为轨迹、性能监控能力最优)
├── 需要产品分析+错误上报能力       → Sentry(崩溃上报) + PostHog(分析、会话回放)
└── 企业级/自定义需求                    → Sentry或Datadog + Google Analytics用于转化漏斗分析
建议通过MCP服务器或CLI工具连接这些服务,这样AI助手可以在调试会话中直接查询生产错误、搜索崩溃模式、拉取用户行为轨迹:
  • Sentry: 已提供MCP服务器 —— 可查询问题、搜索事件、获取堆栈跟踪
  • PostHog: 已提供MCP服务器 —— 可查询分析事件、检查功能开关、搜索错误事件
  • Firebase: 可使用CLI工具(
    firebase crashlytics:*
    ) —— 列出崩溃、下载报告

Observability Stack

可观测技术栈

text
Presentation Layer  -> SwiftUI error state + centralized ErrorHandling
Application Layer   -> ErrorReporter protocol (abstracts Sentry/Crashlytics)
Logging Layer       -> os.Logger with subsystem/category and privacy annotations
Diagnostics Layer   -> MetricKit (OOM, watchdog kills, hangs — out-of-process)
Crash Layer         -> Sentry OR Crashlytics (not both for fatals) + dSYMs
text
表示层  -> SwiftUI错误状态 + 中心化错误处理
应用层   -> ErrorReporter协议(抽象Sentry/Crashlytics能力)
日志层       -> 带子系统/分类和隐私注解的os.Logger
诊断层   -> MetricKit(内存不足、看门狗终止、卡顿 —— 进程外采集)
崩溃层         -> Sentry或Crashlytics(致命错误不要同时使用两者) + dSYMs

Quick Decision Trees

快速决策树

"Should I use try? here?"

"这里可以使用try?吗?"

Is this a best-effort operation where failure is genuinely irrelevant?
├── YES (temp file cleanup, optional cache read, cosmetic prefetch)
│   └── try? is acceptable
└── NO (network, persistence, auth, user-facing, payment, navigation)
    └── MUST use do/catch with Logger.error() + ErrorReporter.recordNonFatal()
这是不是一个失败完全不影响核心逻辑的尽力而为操作?
├── 是(临时文件清理、非必要缓存读取、非核心资源预加载)
│   └── 可以使用try?
└── 否(网络、持久化、鉴权、用户面向功能、支付、导航)
    └── 必须使用do/catch搭配Logger.error() + ErrorReporter.recordNonFatal()

"What logging API should I use?"

"我应该使用什么日志API?"

Is this production code?
├── YES -> os.Logger with privacy annotations
│   ├── Debug tracing        -> .debug (free in production, not persisted)
│   ├── Contextual info      -> .info (memory-only, captured on faults)
│   ├── Operational events   -> .notice (persisted to disk)
│   ├── Recoverable errors   -> .error (always persisted)
│   └── Bugs / unrecoverable -> .fault (persisted + process chain)
└── NO (unit tests, playgrounds, scripts)
    └── print() is fine
这是生产环境代码吗?
├── 是 -> 使用带隐私注解的os.Logger
│   ├── 调试追踪        -> .debug(生产环境无性能损耗、不会持久化)
│   ├── 上下文信息      -> .info(仅内存存储、故障时会被采集)
│   ├── 运营事件   -> .notice(持久化到磁盘)
│   ├── 可恢复错误   -> .error(强制持久化)
│   └── Bug/不可恢复错误 -> .fault(持久化 + 记录进程链)
└── 否(单元测试、playground、脚本)
    └── 可以使用print()

"How should this catch block look?"

"catch块应该怎么写?"

catch {
    // 1. ALWAYS: Structured log with privacy annotations
    Logger.<category>.error("Operation failed: \(error.localizedDescription, privacy: .public)")

    // 2. ALWAYS: Report to crash SDK
    ErrorReporter.shared.recordNonFatal(error, context: ["operation": "..."])

    // 3. CONDITIONALLY: User feedback (if user-facing operation)
    // 4. CONDITIONALLY: Recovery action (retry, rollback, logout)
}
catch {
    // 1. 强制要求:带隐私注解的结构化日志
    Logger.<category>.error("Operation failed: \(error.localizedDescription, privacy: .public)")

    // 2. 强制要求:上报到崩溃SDK
    ErrorReporter.shared.recordNonFatal(error, context: ["operation": "..."])

    // 3. 可选:用户反馈(如果是用户面向操作)
    // 4. 可选:恢复动作(重试、回滚、登出)
}

"Is this Task {} safe?"

"这个Task {}是安全的吗?"

Does the Task body contain try or await that can throw?
├── YES -> MUST wrap in do/catch with observability inside the Task
│   └── Also: distinguish CancellationError (normal) from real errors
└── NO  -> Task {} is fine as-is
Task体内是否包含可能抛出异常的try或await?
├── 是 -> 必须在Task内部用do/catch包裹并添加可观测逻辑
│   └── 另外:需要区分CancellationError(正常流程)和实际错误
└── 否  -> 可以直接使用Task {}

Logging Configuration State

日志配置状态

On first use of any scanning workflow, check for
.claude/ios-logging-config.md
in the project root. If it doesn't exist, run the Configuration Phase below before scanning. If it exists, read it and use those preferences for all fixes.
首次使用任何扫描工作流时,检查项目根目录下是否存在
.claude/ios-logging-config.md
。如果不存在,在扫描前先执行下方的配置阶段。如果存在,读取该文件并在所有修复操作中使用其中的偏好设置。

Configuration Phase (runs once per project)

配置阶段(每个项目执行一次)

Ask the user these questions and persist answers to
.claude/ios-logging-config.md
:
  1. Crash SDK — "Which crash reporting SDK does this project use?"
    • Sentry / Firebase Crashlytics / Datadog / Bugsnag / None (os.Logger only)
    • If none yet: recommend Sentry (best observability) or Crashlytics (if Firebase-heavy)
  2. ErrorReporter protocol — "Do you have a centralized ErrorReporter protocol?"
    • Yes → ask for the type name and import path
    • No → offer to create one wrapping their chosen SDK
  3. Logger setup — "Do you have an os.Logger extension with categories?"
    • Yes → ask for the extension location
    • No → offer to create one with standard categories (networking, persistence, auth, ui)
  4. PII sensitivity — "What data sensitivity level?"
    • Standard (default privacy annotations)
    • Health/HIPAA (aggressive
      .private
      , no PHI in logs)
    • Finance/PCI (redact all financial data)
  5. Preferred fix style — "How should I apply fixes?"
    • Minimal: add logging to existing catch blocks, don't restructure code
    • Full: replace
      try?
      with
      do/catch
      , add error states, restructure where needed
询问用户以下问题并将答案持久化到
.claude/ios-logging-config.md
  1. 崩溃SDK —— "本项目使用哪个崩溃上报SDK?"
    • Sentry / Firebase Crashlytics / Datadog / Bugsnag / 无(仅使用os.Logger)
    • 如果还未选型:推荐Sentry(可观测能力最优)或Crashlytics(重度依赖Firebase的场景)
  2. ErrorReporter协议 —— "你们有中心化的ErrorReporter协议吗?"
    • 有 → 询问类型名和导入路径
    • 无 → 提供封装所选SDK的协议实现
  3. Logger配置 —— "你们有带分类的os.Logger扩展吗?"
    • 有 → 询问扩展文件位置
    • 无 → 提供包含标准分类(网络、持久化、鉴权、UI)的扩展实现
  4. PII敏感等级 —— "数据敏感等级是多少?"
    • 标准(默认隐私注解)
    • 医疗/HIPAA(严格使用
      .private
      、日志中不包含PHI)
    • 金融/PCI(脱敏所有金融数据)
  5. 修复风格偏好 —— "我应该如何应用修复?"
    • 最小化:为现有catch块添加日志、不重构代码
    • 完整:将
      try?
      替换为
      do/catch
      、添加错误状态、必要时重构代码

Config file format:
.claude/ios-logging-config.md

配置文件格式:
.claude/ios-logging-config.md

markdown
---
crash_sdk: sentry
error_reporter_type: ErrorReporter
error_reporter_import: "import ErrorReporting"
logger_extension: "Sources/Core/Logger+Extensions.swift"
logger_subsystem: "Bundle.main.bundleIdentifier!"
pii_level: standard
fix_style: full
---
The config is a simple YAML frontmatter file. The skill reads it at the start of every scanning workflow and uses the values to generate correct import statements, SDK calls, and Logger patterns without asking the user again.
markdown
---
crash_sdk: sentry
error_reporter_type: ErrorReporter
error_reporter_import: "import ErrorReporting"
logger_extension: "Sources/Core/Logger+Extensions.swift"
logger_subsystem: "Bundle.main.bundleIdentifier!"
pii_level: standard
fix_style: full
---
配置文件是简单的YAML前置元数据文件。本技能会在每个扫描工作流启动时读取该文件,使用其中的数值生成正确的导入语句、SDK调用和Logger模式,无需重复询问用户。

Workflows

工作流

Workflow: Scan Project for Silent Failures

工作流:扫描项目中的静默故障

When: User asks to "scan for silent failures", "audit error handling", "find missing logging", "check for try?", or any variant of "make sure nothing fails silently."
This is the primary scanning workflow — modeled after ios-security-audit's Phase 0 → Scan → Report pattern.
触发时机: 用户要求“扫描静默故障”、“审计错误处理”、“查找缺失的日志”、“检查try?使用”,或任何类似“确保没有功能静默失败”的请求。
这是核心扫描工作流——参考iOS安全审计的阶段0→扫描→报告模式设计。

Phase 0: Discover & Configure

阶段0:发现与配置

  1. Check for
    .claude/ios-logging-config.md
    — if missing, run Configuration Phase above
  2. Discover project structure:
    • Scan for
      .xcodeproj
      /
      .xcworkspace
      to list all targets
    • Count
      .swift
      files per target
    • Detect if app has extensions (widget, notification service, watch, etc.)
  3. Present scope menu to user:
Silent Failure Scan — choose scope:

Target scope:
  A: Main target only (~5 min)
  B: All targets including extensions (~10 min)
  C: Specific target (you specify)

Scan depth:
  1: Critical patterns only (try?, Task {}, print(), empty catch)
  2: Full scan (adds Combine, URLSession status, NotificationCenter, Core Data, BGTask)
  3: Full + infrastructure (adds dSYM check, extension SDK init, MetricKit, privacy manifests)

Example: "B2" = all targets, full scan
  1. User confirms (e.g., "A1" or "B3") before scanning begins
  1. 检查
    .claude/ios-logging-config.md
    —— 如果缺失,执行上方的配置阶段
  2. 发现项目结构:
    • 扫描
      .xcodeproj
      /
      .xcworkspace
      列出所有target
    • 统计每个target下的
      .swift
      文件数量
    • 检测应用是否包含扩展(小组件、通知服务、手表应用等)
  3. 向用户展示扫描范围菜单:
静默故障扫描 —— 选择范围:

Target范围:
  A: 仅主target(约5分钟)
  B: 所有target包括扩展(约10分钟)
  C: 指定target(用户自行指定)

扫描深度:
  1: 仅核心模式(try?、Task {}、print()、空catch)
  2: 全量扫描(新增Combine、URLSession状态、NotificationCenter、Core Data、BGTask检查)
  3: 全量+基础设施检查(新增dSYM检查、扩展SDK初始化、MetricKit、隐私清单检查)

示例:"B2" = 所有target、全量扫描
  1. 用户确认(例如:"A1"或"B3")后再开始扫描

Phase 1: Scan

阶段1:扫描

Run grep-based detection first (zero-token, fast), then semantic review on flagged files.
Depth 1 — Critical patterns:
PatternDetectionFix
try?
on non-trivial operations
grep -rn 'try?' --include='*.swift'
Replace with
do/catch
+ Logger + ErrorReporter
Task {}
/
Task.detached {}
with throwing code
grep -rn 'Task\s*{' --include='*.swift'
— then check if body has
try
/
await
without
do/catch
Wrap in
do/catch
, distinguish CancellationError
print(
in production code
grep -rn 'print(' --include='*.swift'
— exclude test targets
Replace with
Logger.<category>.<level>()
with privacy annotations
Empty catch blocks
grep -rn 'catch\s*{' --include='*.swift'
— then check if body is empty or only has
break
/
return
Add Logger.error + ErrorReporter.recordNonFatal
Catch blocks with only
print
Semantic: catch blocks where the only action is
print(error)
Add Logger + ErrorReporter, remove print
else
with silent return
Semantic: guard/if-else where the else branch returns/breaks without loggingAdd Logger.warning explaining what condition was unexpected
Depth 2 — Full scan (adds to depth 1):
PatternDetectionFix
.replaceError()
killing Combine pipelines
grep -rn '.replaceError' --include='*.swift'
Move error handling inside flatMap
receiveCompletion
with only print
Semantic: sink completion handlers with just printAdd Logger + ErrorReporter
URLSession without status code checkSemantic:
URLSession.shared.data(
without
httpResponse.statusCode
Add HTTP status validation + error reporting
NotificationCenter observer not storedSemantic:
addObserver(forName:
return value discarded
Store token, add typed Notification.Name
Core Data
try? context.save()
grep -rn 'try?.*save()' --include='*.swift'
Replace with do/catch, NSError userInfo extraction, rollback
.task {}
with
try?
grep -rn 'try?' --include='*.swift'
in
.task
context
Replace with do/catch, CancellationError filter
BGTask without do/catchSemantic:
BGProcessingTask
/
BGAppRefreshTask
handlers
Add do/catch + expirationHandler
Depth 3 — Infrastructure (adds to depth 2):
CheckDetectionFix
dSYM configurationCheck
Build Settings
for
DEBUG_INFORMATION_FORMAT
Set to
DWARF with dSYM File
for all targets
Extension SDK initializationCheck extension entry points for crash SDK
start()
Add separate SDK init + disable autoSessionTracking
MetricKit subscriber
grep -rn 'MXMetricManager' --include='*.swift'
Add MXMetricManagerSubscriber if missing
PrivacyInfo.xcprivacyCheck for file existenceCreate if missing (required since May 2024)
Dual crash reporter conflictsCheck for both Sentry + Crashlytics initializationWarn about signal handler conflicts
首先运行基于grep的检测(零token消耗、速度快),然后对标记的文件进行语义审查。
深度1 —— 核心模式:
模式检测方式修复方案
非核心操作外的
try?
使用
grep -rn 'try?' --include='*.swift'
替换为
do/catch
+ Logger + ErrorReporter
包含抛出代码的
Task {}
/
Task.detached {}
grep -rn 'Task\s*{' --include='*.swift'
—— 然后检查体内是否有未被
do/catch
包裹的
try
/
await
do/catch
包裹,区分CancellationError
生产代码中的
print(
grep -rn 'print(' --include='*.swift'
—— 排除测试target
替换为带隐私注解的
Logger.<category>.<level>()
空catch块
grep -rn 'catch\s*{' --include='*.swift'
—— 然后检查块内是否为空或仅包含
break
/
return
添加Logger.error + ErrorReporter.recordNonFatal
仅包含print的catch块语义检测:catch块内唯一操作是
print(error)
添加Logger + ErrorReporter,移除print
静默返回的
else
分支
语义检测:guard/if-else的else分支直接返回/中断且无日志添加Logger.warning说明意外触发的条件
深度2 —— 全量扫描(在深度1基础上新增):
模式检测方式修复方案
终止Combine pipeline的
.replaceError()
grep -rn '.replaceError' --include='*.swift'
将错误处理移到flatMap内部
仅包含print的
receiveCompletion
语义检测:sink完成处理器仅包含print添加Logger + ErrorReporter
未检查状态码的URLSession语义检测:
URLSession.shared.data(
未校验
httpResponse.statusCode
添加HTTP状态校验 + 错误上报
未存储的NotificationCenter观察者语义检测:
addObserver(forName:
返回值被丢弃
存储token,添加类型化的Notification.Name
Core Data的
try? context.save()
grep -rn 'try?.*save()' --include='*.swift'
替换为do/catch、提取NSError userInfo、回滚操作
.task {}
中的
try?
扫描
.task
上下文中的
grep -rn 'try?' --include='*.swift'
替换为do/catch、过滤CancellationError
没有do/catch的BGTask语义检测:
BGProcessingTask
/
BGAppRefreshTask
处理器
添加do/catch + 过期处理器
深度3 —— 基础设施(在深度2基础上新增):
检查项检测方式修复方案
dSYM配置检查
Build Settings
中的
DEBUG_INFORMATION_FORMAT
所有target设置为
DWARF with dSYM File
扩展SDK初始化检查扩展入口点是否调用崩溃SDK的
start()
添加独立的SDK初始化 + 禁用autoSessionTracking
MetricKit订阅者
grep -rn 'MXMetricManager' --include='*.swift'
如果缺失添加MXMetricManagerSubscriber
PrivacyInfo.xcprivacy检查文件是否存在如果缺失创建(2024年5月起强制要求)
双崩溃上报器冲突检查是否同时初始化Sentry和Crashlytics警告信号处理器冲突风险

Phase 2: Report

阶段2:报告

Output findings grouped by severity:
undefined
按严重程度分组输出发现的问题:
undefined

Silent Failure Scan Report

静默故障扫描报告

Configuration

配置

  • SDK: [from config]
  • Scope: [user choice]
  • Files scanned: N
  • SDK: [来自配置文件]
  • 扫描范围: [用户选择的范围]
  • 扫描文件数: N

CRITICAL (errors vanishing completely)

严重(错误完全丢失)

[try? on network/auth/payment, Task {} swallowing, empty catch blocks]
[网络/鉴权/支付场景的try?、Task {}吞错、空catch块]

HIGH (errors logged locally but not reported remotely)

高危(错误仅本地记录未远程上报)

[catch blocks with only print() or Logger but no ErrorReporter]
[catch块仅包含print()或Logger但未调用ErrorReporter]

MEDIUM (weak observability)

中危(可观测性不足)

[missing privacy annotations, missing CancellationError filter, URLSession status unchecked]
[缺失隐私注解、未过滤CancellationError、未校验URLSession状态]

Summary

汇总

SeverityCount
CriticalN
HighN
MediumN
TotalN
严重程度数量
严重N
高危N
中危N
总计N

Auto-fix available

可自动修复

[List of files where the skill can apply fixes automatically using the config preferences]

After the report, offer: "Should I fix these? I'll use [SDK from config] and [fix style from config]."
[本技能可使用配置偏好自动修复的文件列表]

报告生成后,提供选项:"需要我修复这些问题吗?我将使用[配置文件中的SDK]和[配置文件中的修复风格]进行修复。"

Workflow: Add Logging to Existing Codebase

工作流:为现有代码库添加日志

When: Setting up observability for an iOS project from scratch, or migrating from print() to Logger.
  1. Run Configuration Phase if
    .claude/ios-logging-config.md
    doesn't exist
  2. Create Logger extensions with subsystem/category (
    references/logger-setup.md
    )
  3. Create ErrorReporter protocol and SDK implementation (
    references/crash-sdk-integration.md
    )
  4. Audit all
    print()
    calls — replace with appropriate Logger level
  5. Audit all
    try?
    usages — convert critical ones to
    do/catch
    (
    references/silent-failures.md
    )
  6. Audit all
    Task {}
    blocks — ensure do/catch wraps any throwing code
  7. Audit Combine pipelines — move error handling inside
    flatMap
    (
    references/silent-failures.md
    )
  8. Add MetricKit subscriber for OOM/watchdog detection (
    references/metrickit.md
    )
  9. Verify dSYMs: Debug Information Format = "DWARF with dSYM File" for all targets
  10. If app has extensions: initialize crash SDK separately in each (
    references/enterprise-patterns.md
    )
触发时机: 从零为iOS项目搭建可观测能力,或从print()迁移到Logger。
  1. 如果
    .claude/ios-logging-config.md
    不存在则执行配置阶段
  2. 创建带子系统/分类的Logger扩展(
    references/logger-setup.md
  3. 创建ErrorReporter协议和SDK实现(
    references/crash-sdk-integration.md
  4. 审计所有
    print()
    调用 —— 替换为合适的Logger级别
  5. 审计所有
    try?
    使用 —— 将核心场景的用法转换为
    do/catch
    references/silent-failures.md
  6. 审计所有
    Task {}
    块 —— 确保所有抛出代码被do/catch包裹
  7. 审计Combine pipeline —— 将错误处理移到
    flatMap
    内部(
    references/silent-failures.md
  8. 添加MetricKit订阅者用于检测内存不足/看门狗终止(
    references/metrickit.md
  9. 验证dSYM配置:所有target的调试信息格式设置为"DWARF with dSYM File"
  10. 如果应用包含扩展:在每个扩展中单独初始化崩溃SDK(
    references/enterprise-patterns.md

Workflow: Review Error Handling in PR

工作流:PR中的错误处理代码审核

When: Code review that touches error handling, networking, persistence, or async code.
  1. Check every
    catch
    block: does it have Logger + ErrorReporter? (
    references/silent-failures.md
    )
  2. Check every
    try?
    : is failure genuinely irrelevant? If not, flag it
  3. Check every
    Task {}
    with
    try
    : is there a do/catch inside?
  4. Check every
    .task {}
    modifier: CancellationError handled separately?
  5. Check Combine chains: error recovery inside
    flatMap
    , not at the pipeline end?
  6. Check Logger calls: privacy annotations on all dynamic strings? (
    references/logger-setup.md
    )
  7. Check for PII in log messages or crash report metadata (
    references/pii-compliance.md
    )
  8. Check URLSession usage: HTTP status codes validated? (
    references/silent-failures.md
    )
触发时机: 涉及错误处理、网络、持久化或异步代码的代码评审。
  1. 检查每个
    catch
    块:是否包含Logger + ErrorReporter?(
    references/silent-failures.md
  2. 检查每个
    try?
    :失败是否真的无关紧要?如果不是则标记
  3. 检查每个包含
    try
    Task {}
    :内部是否有do/catch?
  4. 检查每个
    .task {}
    修饰器:是否单独处理了CancellationError?
  5. 检查Combine链:错误恢复是否在
    flatMap
    内部而非pipeline末尾?
  6. 检查Logger调用:所有动态字符串是否都有隐私注解?(
    references/logger-setup.md
  7. 检查日志消息或崩溃报告元数据中是否包含PII(
    references/pii-compliance.md
  8. 检查URLSession使用:是否校验了HTTP状态码?(
    references/silent-failures.md

Workflow: Integrate Crash Reporting SDK

工作流:集成崩溃上报SDK

When: Adding Sentry, Crashlytics, or PostHog to an iOS project.
  1. Choose primary fatal crash reporter (only one!) —
    references/crash-sdk-integration.md
  2. Implement ErrorReporter protocol wrapping chosen SDK
  3. Add breadcrumbs before risky operations (DB migrations, payments, auth flows)
  4. Configure dSYM upload in build phases
  5. If multiple SDKs needed: disable crash handler on secondary (
    references/crash-sdk-integration.md
    )
  6. Test with intentional crash and non-fatal to verify symbolication
  7. For extensions: separate SDK init per extension target (
    references/enterprise-patterns.md
    )
触发时机: 为iOS项目添加Sentry、Crashlytics或PostHog。
  1. 选择主致命崩溃上报器(仅选一个!) ——
    references/crash-sdk-integration.md
  2. 实现封装所选SDK的ErrorReporter协议
  3. 在风险操作(数据库迁移、支付、鉴权流程)前添加用户行为轨迹
  4. 在构建阶段配置dSYM上传
  5. 如果需要使用多个SDK:禁用次要SDK的崩溃处理器(
    references/crash-sdk-integration.md
  6. 用主动触发的崩溃和非致命错误测试验证符号解析正常
  7. 针对扩展:每个扩展target单独初始化SDK(
    references/enterprise-patterns.md

Workflow: Connect Remote Logging for AI-Assisted Debugging

工作流:对接远程日志实现AI辅助调试

When: Setting up the development environment to query production errors from your AI assistant.
  1. Sentry — Add Sentry MCP server to your Claude Code / IDE config:
    • claude mcp add sentry
      or configure in
      .mcp.json
    • Enables: querying recent issues, searching events, getting stack traces and breadcrumbs
  2. PostHog — Add PostHog MCP server:
    • Configure with your PostHog API key and project ID
    • Enables: querying analytics events, checking feature flags, searching error events
  3. Firebase — Install Firebase CLI:
    • npm install -g firebase-tools && firebase login
    • Enables:
      firebase crashlytics:symbols:upload
      , listing recent crashes
  4. Verify connectivity — Ask your AI assistant to "check recent crashes in Sentry" or "what errors happened today in PostHog" to confirm the integration works
This connectivity is what makes remote logging truly powerful — instead of context-switching to dashboards, your debugging workflow stays in the editor.
触发时机: 配置开发环境让AI助手可以查询生产错误。
  1. Sentry —— 向Claude Code/IDE配置中添加Sentry MCP服务器:
    • 执行
      claude mcp add sentry
      或在
      .mcp.json
      中配置
    • 支持能力:查询近期问题、搜索事件、获取堆栈跟踪和用户行为轨迹
  2. PostHog —— 添加PostHog MCP服务器:
    • 用你的PostHog API密钥和项目ID配置
    • 支持能力:查询分析事件、检查功能开关、搜索错误事件
  3. Firebase —— 安装Firebase CLI:
    • 执行
      npm install -g firebase-tools && firebase login
    • 支持能力:
      firebase crashlytics:symbols:upload
      、列出近期崩溃
  4. 验证连通性 —— 让AI助手“查询Sentry中的近期崩溃”或“PostHog中今天发生了什么错误”确认集成正常
这种连通性是远程日志的真正价值所在——你不用切换到各种仪表板,调试工作流可以全程留在编辑器中。

Reference Files

参考文件

FileWhen to read
references/silent-failures.md
Writing or reviewing error handling code, diagnosing vanishing errors
references/logger-setup.md
Setting up os.Logger, choosing log levels, adding privacy annotations
references/crash-sdk-integration.md
Integrating Sentry/Crashlytics/PostHog, ErrorReporter protocol, breadcrumbs
references/metrickit.md
Adding MetricKit for OOM/watchdog/hang detection
references/objc-exceptions.md
Bridging Swift/ObjC error handling, NSException edge cases
references/pii-compliance.md
GDPR/CCPA logging compliance, privacy manifests, redaction patterns
references/enterprise-patterns.md
Centralized error handling, retry with backoff, extension monitoring
文件适用场景
references/silent-failures.md
编写或审核错误处理代码、排查消失的错误
references/logger-setup.md
配置os.Logger、选择日志级别、添加隐私注解
references/crash-sdk-integration.md
集成Sentry/Crashlytics/PostHog、实现ErrorReporter协议、添加用户行为轨迹
references/metrickit.md
添加MetricKit实现内存不足/看门狗终止/卡顿检测
references/objc-exceptions.md
桥接Swift/ObjC错误处理、处理NSException边缘场景
references/pii-compliance.md
GDPR/CCPA日志合规、隐私清单、脱敏模式
references/enterprise-patterns.md
中心化错误处理、带退避的重试、扩展监控