MetricKit API reference for field diagnostics - MXMetricPayload, MXDiagnosticPayload, MXCallStackTree parsing, crash and hang collection
View on GitHubSelect agents to install to:
npx add-skill https://github.com/CharlesWiltgen/Axiom/blob/main/.claude-plugin/plugins/axiom/skills/axiom-metrickit-ref/SKILL.md -a claude-code --skill axiom-metrickit-refInstallation paths:
.claude/skills/axiom-metrickit-ref/# MetricKit API Reference
Complete API reference for collecting field performance metrics and diagnostics using MetricKit.
## Overview
MetricKit provides aggregated, on-device performance and diagnostic data from users who opt into sharing analytics. Data is delivered daily (or on-demand in development).
## When to Use This Reference
Use this reference when:
- Setting up MetricKit subscriber in your app
- Parsing MXMetricPayload or MXDiagnosticPayload
- Symbolicating MXCallStackTree crash data
- Understanding background exit reasons (jetsam, watchdog)
- Integrating MetricKit with existing crash reporters
For hang diagnosis workflows, see `axiom-hang-diagnostics`.
For general profiling with Instruments, see `axiom-performance-profiling`.
For memory debugging including jetsam, see `axiom-memory-debugging`.
## Common Gotchas
1. **24-hour delay** — MetricKit data arrives once daily; it's not real-time debugging
2. **Call stacks require symbolication** — MXCallStackTree frames are unsymbolicated; keep dSYMs
3. **Opt-in only** — Only users who enable "Share with App Developers" contribute data
4. **Aggregated, not individual** — You get counts and averages, not per-user traces
5. **Simulator doesn't work** — MetricKit only collects on physical devices
**iOS Version Support**:
| Feature | iOS Version |
|---------|-------------|
| Basic metrics (battery, CPU, memory) | iOS 13+ |
| Diagnostic payloads | iOS 14+ |
| Hang diagnostics | iOS 14+ |
| Launch diagnostics | iOS 16+ |
| Immediate delivery in dev | iOS 15+ |
## Part 1: Setup
### Basic Integration
```swift
import MetricKit
class AppMetricsSubscriber: NSObject, MXMetricManagerSubscriber {
override init() {
super.init()
MXMetricManager.shared.add(self)
}
deinit {
MXMetricManager.shared.remove(self)
}
// MARK: - MXMetricManagerSubscriber
func didReceive(_ payloads: [MXMetricPayload]) {
for payload in payloads {
processMetrics(payload)