
Metrickit
- 2.1k installs
- 944 repo stars
- Updated July 15, 2026
- dpearson2699/swift-ios-skills
metrickit is an agent skill that Collect and analyze on-device performance metrics and crash diagnostics using MetricKit. Use when setting up MXMetricManager, handling MXMetricPayload or MXDiag.
About
Collect and analyze on-device performance metrics and crash diagnostics using MetricKit Use when setting up MXMetricManager handling MXMetricPayload or MXDiagnosticPayload processing crash hang disk-write diagnostics via MXCallStackTree adding custom signpost metrics correcting mxSignpost or extended launch measurement code or uploading telemetry to an analytics backend name metrickit description Collect and analyze on-device performance metrics and crash diagnostics using MetricKit Use when setting up MXMetricManager handling MXMetricPayload or MXDiagnosticPayload processing crash hang disk-write diagnostics via MXCallStackTree adding custom signpost metrics correcting mxSignpost or extended launch measurement code or uploading telemetry to an analytics backend MetricKit Collect aggregated performance metrics and crash diagnostics from production devices using MetricKit The framework delivers daily metric payloads CPU memory launch time hang rate animation hitches network usage and diagnostic payloads crashes hangs disk-write exceptions with call-stack trees for triage Contents Subscriber Setup subscriber-setup Receiving Metric Payloads receiving-metric-payloads Receiving Diagnos.
- [Subscriber Setup](#subscriber-setup)
- [Receiving Metric Payloads](#receiving-metric-payloads)
- [Receiving Diagnostic Payloads](#receiving-diagnostic-payloads)
- [Key Metrics](#key-metrics)
- [Call Stack Trees](#call-stack-trees)
Metrickit by the numbers
- 2,116 all-time installs (skills.sh)
- +114 installs in the week ending Jul 29, 2026 (Skillselion tracking)
- Ranked #366 of 2,159 Testing & QA skills by installs in the Skillselion catalog
- Security screen: LOW risk (skills.sh audit)
- Data as of Jul 31, 2026 (Skillselion catalog sync)
metrickit capabilities & compatibility
- Capabilities
- [subscriber setup](#subscriber setup) · [receiving metric payloads](#receiving metric pa · [receiving diagnostic payloads](#receiving diagn · [key metrics](#key metrics) · [call stack trees](#call stack trees)
- Use cases
- documentation
What metrickit says it does
--- name: metrickit description: "Collect and analyze on-device performance metrics and crash diagnostics using MetricKit.
MetricKit starts accumulating reports after the first access to `MXMetricManager.shared`.
When backfilling, state precisely that `pastPayloads` and `pastDiagnosticPayloads` return reports generated since the last allocation of the shared manager instance.
The array may contain multiple payloads if prior deliveries were missed.
npx skills add https://github.com/dpearson2699/swift-ios-skills --skill metrickitAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 2.1k |
|---|---|
| repo stars | ★ 944 |
| Security audit | 3 / 3 scanners passed |
| Last updated | July 15, 2026 |
| Repository | dpearson2699/swift-ios-skills ↗ |
What problem does metrickit solve for developers using this skill?
Collect and analyze on-device performance metrics and crash diagnostics using MetricKit. Use when setting up MXMetricManager, handling MXMetricPayload or MXDiagnosticPayload, processing crash/hang/dis
Who is it for?
Developers who need metrickit patterns described in the cached skill documentation.
Skip if: Skip when docs are empty or the task is outside the skill's documented scope.
When should I use this skill?
Collect and analyze on-device performance metrics and crash diagnostics using MetricKit. Use when setting up MXMetricManager, handling MXMetricPayload or MXDiagnosticPayload, processing crash/hang/dis
What you get
Actionable workflows and conventions from SKILL.md for metrickit.
- MetricKit subscriber implementation
- Payload persistence layer
- Telemetry review notes
Files
MetricKit
Collect aggregated performance metrics and crash diagnostics from production devices using MetricKit. The framework delivers daily metric payloads (CPU, memory, launch time, hang rate, animation hitches, network usage) and diagnostic payloads (crashes, hangs, disk-write exceptions) with call-stack trees for triage.
Contents
- Subscriber Setup
- Receiving Metric Payloads
- Receiving Diagnostic Payloads
- Key Metrics
- Call Stack Trees
- Custom Signpost Metrics
- Exporting and Uploading Payloads
- Extended Launch Measurement
- Xcode Organizer Integration
- Scope Boundaries
- Common Mistakes
- Review Checklist
- References
Subscriber Setup
Register a subscriber as early as possible — ideally in application(_:didFinishLaunchingWithOptions:) or App.init. MetricKit starts accumulating reports after the first access to MXMetricManager.shared. When backfilling, state precisely that pastPayloads and pastDiagnosticPayloads return reports generated since the last allocation of the shared manager instance.
import MetricKit
final class MetricsSubscriber: NSObject, MXMetricManagerSubscriber {
static let shared = MetricsSubscriber()
func subscribe() {
let manager = MXMetricManager.shared
manager.add(self)
// Reports generated since the last allocation of the shared manager.
processMetricPayloads(manager.pastPayloads)
processDiagnosticPayloads(manager.pastDiagnosticPayloads)
}
func unsubscribe() {
MXMetricManager.shared.remove(self)
}
func didReceive(_ payloads: [MXMetricPayload]) {
processMetricPayloads(payloads)
}
func didReceive(_ payloads: [MXDiagnosticPayload]) {
processDiagnosticPayloads(payloads)
}
}UIKit Registration
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
MetricsSubscriber.shared.subscribe()
return true
}SwiftUI Registration
@main
struct MyApp: App {
init() {
MetricsSubscriber.shared.subscribe()
}
var body: some Scene {
WindowGroup { ContentView() }
}
}Receiving Metric Payloads
MXMetricPayload arrives approximately once per 24 hours containing aggregated metrics. The array may contain multiple payloads if prior deliveries were missed.
func didReceive(_ payloads: [MXMetricPayload]) {
for payload in payloads {
let begin = payload.timeStampBegin
let end = payload.timeStampEnd
let version = payload.latestApplicationVersion
// Persist raw JSON before processing
let jsonData = payload.jsonRepresentation()
persistPayload(jsonData, from: begin, to: end)
enqueueMetricProcessing(jsonData)
}
}Availability: MXMetricPayload — iOS 13.0+, iPadOS 13.0+, Mac Catalyst 13.1+, macOS 10.15+, visionOS 1.0+
Receiving Diagnostic Payloads
MXDiagnosticPayload delivers crash, hang, CPU exception, disk-write, and app-launch diagnostics where supported. On iOS 15+ and macOS 12+, supported diagnostics can arrive as soon as available rather than bundled with the daily report.
func didReceive(_ payloads: [MXDiagnosticPayload]) {
for payload in payloads {
let jsonData = payload.jsonRepresentation()
persistPayload(jsonData)
enqueueDiagnosticProcessing(jsonData)
}
}In the background processor, inspect the typed diagnostic arrays after the raw payload is durable:
func processDiagnosticPayload(_ payload: MXDiagnosticPayload) {
if let crashes = payload.crashDiagnostics {
for crash in crashes {
handleCrash(crash)
}
}
if let hangs = payload.hangDiagnostics {
for hang in hangs {
handleHang(hang)
}
}
if let diskWrites = payload.diskWriteExceptionDiagnostics {
for diskWrite in diskWrites {
handleDiskWrite(diskWrite)
}
}
if let cpuExceptions = payload.cpuExceptionDiagnostics {
for cpuException in cpuExceptions {
handleCPUException(cpuException)
}
}
#if os(iOS) || targetEnvironment(macCatalyst) || os(visionOS)
if #available(iOS 16.0, macCatalyst 16.0, visionOS 1.0, *),
let launchDiagnostics = payload.appLaunchDiagnostics {
for launchDiagnostic in launchDiagnostics {
handleSlowLaunch(launchDiagnostic)
}
}
#endif
}Availability: MXDiagnosticPayload — iOS 14.0+, iPadOS 14.0+, Mac Catalyst 14.0+, macOS 12.0+, visionOS 1.0+. appLaunchDiagnostics requires iOS 16.0+, iPadOS 16.0+, Mac Catalyst 16.0+, or visionOS 1.0+.
Key Metrics
Launch Time — MXAppLaunchMetric
if let launch = payload.applicationLaunchMetrics {
let firstDraw = launch.histogrammedTimeToFirstDraw
let optimized = launch.histogrammedOptimizedTimeToFirstDraw
let resume = launch.histogrammedApplicationResumeTime
let extended = launch.histogrammedExtendedLaunch
}Run Time — MXAppRunTimeMetric
if let runTime = payload.applicationTimeMetrics {
let fg = runTime.cumulativeForegroundTime // Measurement<UnitDuration>
let bg = runTime.cumulativeBackgroundTime
let bgAudio = runTime.cumulativeBackgroundAudioTime
let bgLocation = runTime.cumulativeBackgroundLocationTime
}CPU, Memory, and Responsiveness
if let cpu = payload.cpuMetrics {
let cpuTime = cpu.cumulativeCPUTime // Measurement<UnitDuration>
}
if let memory = payload.memoryMetrics {
let peakMemory = memory.peakMemoryUsage // Measurement<UnitInformationStorage>
}
if let responsiveness = payload.applicationResponsivenessMetrics {
let hangTime = responsiveness.histogrammedApplicationHangTime
}
if let animation = payload.animationMetrics {
let scrollHitchRate = animation.scrollHitchTimeRatio // Measurement<Unit>
}Network and Cellular
if let network = payload.networkTransferMetrics {
let wifiUp = network.cumulativeWifiUpload // Measurement<UnitInformationStorage>
let wifiDown = network.cumulativeWifiDownload
let cellUp = network.cumulativeCellularUpload
let cellDown = network.cumulativeCellularDownload
}App Exit Metrics
if let exits = payload.applicationExitMetrics {
let fg = exits.foregroundExitData
let bg = exits.backgroundExitData
// Inspect normal, abnormal, watchdog, memory, etc.
}Call Stack Trees
MXCallStackTree is attached to each diagnostic. Use jsonRepresentation() to extract frame data, then symbolicate with atos or by uploading dSYMs to your analytics service.
See references/metrickit-patterns.md for crash/hang handling code and JSON structure details.
Availability: MXCallStackTree — iOS 14.0+, iPadOS 14.0+, Mac Catalyst 14.0+, macOS 12.0+, visionOS 1.0+
Custom Signpost Metrics
Use mxSignpost with a MetricKit log handle to capture custom performance intervals. Leave the advanced dso, signpostID, and format parameters at their documented defaults. Custom metrics appear in the daily MXMetricPayload under signpostMetrics; call that out when reviewing custom MetricKit instrumentation. When correcting custom signpost code, explicitly name MXMetricPayload.signpostMetrics so the caller knows where the data lands. Do not allocate or pass an OSSignpostID for the basic MetricKit pattern; use the defaulted mxSignpost(.begin/.end, log:name:) calls unless there is a specific overlapping-interval reason to do otherwise.
let metricLog = MXMetricManager.makeLogHandle(category: "Networking")
mxSignpost(.begin, log: metricLog, name: "DataFetch")
defer { mxSignpost(.end, log: metricLog, name: "DataFetch") }
let data = try await fetchData()See references/metrickit-patterns.md for signpost emission patterns and reading custom metrics from payloads.
Exporting and Uploading Payloads
Both payload types provide jsonRepresentation() for serialization. Always persist raw JSON to disk before processing. Use pastPayloads and pastDiagnosticPayloads on launch to retrieve reports generated since the last allocation of the shared manager instance.
See references/metrickit-patterns.md for export code and past payload retrieval.
Extended Launch Measurement
Track post-first-draw setup work as part of the launch metric on iOS 16+, iPadOS 16+, Mac Catalyst 16+, macOS 13+, and visionOS 1+:
let taskID = MXLaunchTaskID("com.example.app.loadDatabase")
try MXMetricManager.extendLaunchMeasurement(forTaskID: taskID)
defer { try? MXMetricManager.finishExtendedLaunchMeasurement(forTaskID: taskID) }
restoreCachedState()When correcting extended launch code, include the whole operational contract: availability is iOS/iPadOS/Mac Catalyst 16+, macOS 13+, and visionOS 1+; call the throwing MXMetricManager type methods on the main thread; start the first task before the first scene becomes active; keep task windows overlapping; finish every task; and stay within the 16-task limit. Extended launch times appear under histogrammedExtendedLaunch in MXAppLaunchMetric.
Xcode Organizer Integration
Xcode Organizer shows aggregated MetricKit data across opted-in users. Use it for trend analysis alongside on-device collection routed to your own backend.
See references/metrickit-patterns.md for Organizer tab details.
Scope Boundaries
Use this skill for production MetricKit ingestion, payload export, custom MetricKit signposts, and diagnostic upload/symbolication. Route SwiftUI runtime stutters, body-update cost, identity churn, and view invalidation fixes to swiftui-performance. Route local Instruments, LLDB, Memory Graph, and xctrace workflows to debugging-instruments. When explaining production telemetry, distinguish daily metric payloads from supported diagnostics that can arrive as soon as available.
Common Mistakes
DON'T: Subscribe to MXMetricManager too late
Allocate MXMetricManager.shared and register the subscriber during app startup so the manager can accumulate reports and deliver any previously undelivered daily reports. Registering from a later view lifecycle hook is too easy to miss.
// WRONG — subscribing in a view controller
override func viewDidLoad() {
super.viewDidLoad()
MXMetricManager.shared.add(self)
}
// CORRECT — subscribe in application(_:didFinishLaunchingWithOptions:)
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions opts: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
MXMetricManager.shared.add(metricsSubscriber)
return true
}DON'T: Ignore MXDiagnosticPayload
Only handling MXMetricPayload means you miss crash, hang, and disk-write diagnostics — the most actionable data MetricKit provides.
// WRONG — only implementing metric callback
func didReceive(_ payloads: [MXMetricPayload]) { /* ... */ }
// CORRECT — implement both callbacks
func didReceive(_ payloads: [MXMetricPayload]) { /* ... */ }
func didReceive(_ payloads: [MXDiagnosticPayload]) { /* ... */ }DON'T: Process payloads without persisting first
Do not assume callback delivery will repeat if your own processing fails. Save the raw JSON before parsing, symbolication, or upload work.
// WRONG — process inline, crash loses data
func didReceive(_ payloads: [MXDiagnosticPayload]) {
for p in payloads {
riskyProcessing(p) // If this crashes, payload is gone
}
}
// CORRECT — persist raw JSON first, then process
func didReceive(_ payloads: [MXDiagnosticPayload]) {
for p in payloads {
let json = p.jsonRepresentation()
try? json.write(to: localCacheURL()) // Safe on disk
Task.detached { self.processAsync(json) }
}
}DON'T: Do heavy work synchronously in didReceive
Apple documents that it is safe to process payloads on a separate thread. Keep the subscriber callback small: persist the JSON, then move expensive parsing or uploading out of the callback.
// WRONG — synchronous upload in callback
func didReceive(_ payloads: [MXMetricPayload]) {
for p in payloads {
let data = p.jsonRepresentation()
URLSession.shared.uploadTask(with: request, from: data).resume() // sync wait
}
}
// CORRECT — persist and dispatch async
func didReceive(_ payloads: [MXMetricPayload]) {
for p in payloads {
let json = p.jsonRepresentation()
persistLocally(json)
Task.detached(priority: .utility) {
await self.uploadToBackend(json)
}
}
}DON'T: Expect immediate data in development
MetricKit aggregates data over 24-hour windows. Payloads do not arrive immediately after instrumenting. Use Xcode Organizer or simulated payloads for faster iteration during development.
DON'T: Invent MetricKit signpost IDs
MXSignpostIntervalData.makeSignpostID(log:) is not documented MetricKit API. For basic MetricKit custom metrics, create an MXMetricManager log handle and call mxSignpost(.begin/.end, log:name:) without OSSignpostID allocation or custom dso, signpostID, or format arguments.
Review Checklist
- [ ]
MXMetricManager.shared.add(subscriber)called inapplication(_:didFinishLaunchingWithOptions:)orApp.init - [ ] Subscriber conforms to
MXMetricManagerSubscriberand inheritsNSObject - [ ] Both
didReceive(_: [MXMetricPayload])anddidReceive(_: [MXDiagnosticPayload])implemented - [ ] Raw
jsonRepresentation()persisted to disk before processing - [ ] Heavy processing dispatched asynchronously after raw payload persistence
- [ ]
MXCallStackTreeJSON uploaded with dSYMs for symbolication - [ ] Custom signpost metrics limited to critical code paths
- [ ]
pastPayloadsandpastDiagnosticPayloadschecked on launch for missed deliveries - [ ] Extended launch tasks call the throwing
MXMetricManagertype methods on the main thread and finish every started task - [ ] Analytics backend accepts and stores MetricKit JSON format
- [ ] Xcode Organizer reviewed for regression trends alongside on-device data
References
- Extended patterns: references/metrickit-patterns.md
- MetricKit framework
- MXMetricManager
- MXMetricManagerSubscriber
- MXMetricPayload
- MXDiagnosticPayload
{
"skill_name": "metrickit",
"evals": [
{
"id": 0,
"prompt": "Review this MetricKit telemetry plan for an iOS app: the subscriber is created in a dashboard view, only didReceive([MXMetricPayload]) is implemented, payloads are parsed and uploaded before saving, and missed reports are ignored. Give corrected guidance with concise Swift where useful.",
"expected_output": "A source-grounded MetricKit setup review that registers early, handles both metric and diagnostic payloads, persists raw JSON before processing, offloads heavier work, and retrieves past reports precisely.",
"files": [],
"expectations": [
"Recommends registering a long-lived MXMetricManagerSubscriber during app startup, such as UIApplication launch or App.init.",
"Implements or explicitly requires both didReceive(_: [MXMetricPayload]) and didReceive(_: [MXDiagnosticPayload]).",
"Persists jsonRepresentation() before parsing, symbolication, or upload work.",
"Moves expensive parsing or uploads out of the subscriber callback after persistence.",
"Uses pastPayloads and pastDiagnosticPayloads, or otherwise addresses missed reports during startup backfill.",
"Does not claim that MetricKit callbacks are a normal immediate development-time signal for daily metric payloads."
]
},
{
"id": 1,
"prompt": "Fix this MetricKit code review comment: the team uses MXSignpostIntervalData.makeSignpostID(log:), passes a custom signpostID into mxSignpost, and calls MXMetricManager.shared.extendLaunchMeasurement without try from a background task. What should the corrected guidance say?",
"expected_output": "A correction-focused answer that removes the fake signpost helper, preserves MetricKit mxSignpost defaults, and uses the current extended launch type methods with availability and main-thread constraints.",
"files": [],
"expectations": [
"States that MXSignpostIntervalData.makeSignpostID(log:) is not the documented MetricKit API.",
"Uses MXMetricManager.makeLogHandle(category:) and mxSignpost(.begin/.end, log:name:) without custom dso, signpostID, or format parameters for the basic MetricKit pattern.",
"States that MetricKit custom signpost metrics appear under MXMetricPayload.signpostMetrics.",
"Uses try MXMetricManager.extendLaunchMeasurement(forTaskID:) and try or try? MXMetricManager.finishExtendedLaunchMeasurement(forTaskID:) as type methods, not shared instance methods.",
"Mentions Apple's operational constraints for extended launch measurement: main thread, early scene activation or state restoration timing, max 16 tasks, overlapping task windows, or finishing every started task."
]
},
{
"id": 2,
"prompt": "My SwiftUI feed stutters in development, Instruments shows a hot body update, and product wants production hang/crash telemetry in our analytics backend. What should the MetricKit skill handle directly, and what should be routed to adjacent skills?",
"expected_output": "A boundary-aware answer that keeps production MetricKit ingestion in scope while routing SwiftUI code remediation and local Instruments profiling details to sibling skills.",
"files": [],
"expectations": [
"Keeps MXMetricManager setup, MXMetricPayload/MXDiagnosticPayload handling, MXHangDiagnostic or MXCrashDiagnostic processing, and backend upload guidance in the MetricKit scope.",
"Routes SwiftUI view invalidation, body-cost, identity, and remediation patterns to the swiftui-performance skill.",
"Routes local Instruments capture, LLDB, Memory Graph, and xctrace workflow details to the debugging-instruments skill.",
"Mentions using MXCallStackTree JSON plus dSYMs or an analytics symbolication pipeline for crash and hang triage.",
"Mentions MetricKit as production telemetry rather than immediate local debugging, including daily aggregation or non-realtime behavior.",
"Does not expand into a full SwiftUI refactor or full Instruments tutorial."
]
}
]
}
MetricKit Extended Patterns
Overflow reference for the metrickit skill. Contains deeper payload analysis, export patterns, custom signpost metrics, and extended launch measurement.
Contents
- Call Stack Trees
- Custom Signpost Metrics
- Exporting and Uploading Payloads
- Past Payloads
- Extended Launch Measurement
- Xcode Organizer Integration
Call Stack Trees
MXCallStackTree is attached to each diagnostic (crash, hang, CPU exception, disk write, app launch). Use jsonRepresentation() to extract and symbolicate.
func handleCrash(_ crash: MXCrashDiagnostic) {
let tree = crash.callStackTree
let treeJSON = tree.jsonRepresentation()
let exceptionType = crash.exceptionType
let signal = crash.signal
let reason = crash.terminationReason
uploadDiagnostic(
type: "crash",
exceptionType: exceptionType,
signal: signal,
reason: reason,
callStack: treeJSON
)
}
func handleHang(_ hang: MXHangDiagnostic) {
let tree = hang.callStackTree
let duration = hang.hangDuration // Measurement<UnitDuration>
uploadDiagnostic(type: "hang", duration: duration, callStack: tree.jsonRepresentation())
}The JSON structure contains an array of call stack frames with binary name, offset, and address. Symbolicate using atos or upload dSYMs to your analytics service.
Availability: MXCallStackTree — iOS 14.0+, iPadOS 14.0+, Mac Catalyst 14.0+, macOS 12.0+, visionOS 1.0+
Custom Signpost Metrics
Use mxSignpost with a MetricKit log handle to capture custom performance intervals. These appear in the daily MXMetricPayload under signpostMetrics.
Creating a Log Handle
let metricLog = MXMetricManager.makeLogHandle(category: "Networking")Emitting Signposts
import os
func fetchData() async throws -> Data {
mxSignpost(.begin, log: metricLog, name: "DataFetch")
let data = try await URLSession.shared.data(from: url).0
mxSignpost(.end, log: metricLog, name: "DataFetch")
return data
}For MetricKit custom metrics, create the log with MXMetricManager.makeLogHandle(category:) and leave the mxSignpost overload's advanced dso, signpostID, and format parameters at their documented defaults.
Reading Custom Metrics from Payload
if let signposts = payload.signpostMetrics {
for metric in signposts {
let name = metric.signpostName // "DataFetch"
let category = metric.signpostCategory // "Networking"
let count = metric.totalCount
if let intervalData = metric.signpostIntervalData {
let avgMemory = intervalData.averageMemory
let cumulativeCPUTime = intervalData.cumulativeCPUTime
}
}
}The system limits the number of custom signpost metrics per log to reduce
on-device overhead. Reserve custom metrics for critical code paths.
Exporting and Uploading Payloads
Both payload types conform to NSSecureCoding and provide jsonRepresentation() for easy serialization.
func persistPayload(_ jsonData: Data, from: Date? = nil, to: Date? = nil) {
let fileName = "metrics_\(ISO8601DateFormatter().string(from: Date())).json"
let url = FileManager.default.temporaryDirectory.appending(path: fileName)
try? jsonData.write(to: url)
}
func uploadPayloads(_ jsonData: Data) {
Task.detached(priority: .utility) {
var request = URLRequest(url: URL(string: "https://api.example.com/metrics")!)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = jsonData
_ = try? await URLSession.shared.data(for: request)
}
}Past Payloads
If the subscriber was not registered when payloads arrived, retrieve them using pastPayloads and pastDiagnosticPayloads. These return reports generated since the last allocation of the shared manager instance.
let pastMetrics = MXMetricManager.shared.pastPayloads
let pastDiags = MXMetricManager.shared.pastDiagnosticPayloadsExtended Launch Measurement
Track post-first-draw setup work (loading databases, restoring state) as part of the launch metric using extended launch measurement on iOS 16+, iPadOS 16+, Mac Catalyst 16+, macOS 13+, and visionOS 1+.
let taskID = MXLaunchTaskID("com.example.app.loadDatabase")
try MXMetricManager.extendLaunchMeasurement(forTaskID: taskID)
defer { try? MXMetricManager.finishExtendedLaunchMeasurement(forTaskID: taskID) }
restoreCachedState()
connectInitialSceneData()Extended launch times appear under histogrammedExtendedLaunch in MXAppLaunchMetric.
Use these throwing type methods on the main thread. Start the first task before or during state restoration, or before the first scene becomes active. The system supports up to 16 tasks; task windows need to overlap, and extended launch measurement ends when all running tasks finish.
Xcode Organizer Integration
Xcode Organizer shows the same MetricKit data aggregated across all users who have opted in to share diagnostics. Use Organizer for trend analysis:
- Metrics tab: Battery, performance, and disk-write metrics over time
- Regressions tab: Automatic detection of metric regressions per version
- Crashes tab: Crash logs with symbolicated stack traces
MetricKit on-device collection complements Organizer by letting you route raw data to your own backend for custom dashboards, alerting, and filtering by user cohort.
Apple Documentation Links
Related skills
How it compares
Use metrickit for on-device Apple MetricKit patterns; use backend APM skills when the task is server-side trace aggregation instead of iOS payload collection.
FAQ
What does metrickit do?
Collect and analyze on-device performance metrics and crash diagnostics using MetricKit. Use when setting up MXMetricManager, handling MXMetricPayload or MXDiagnosticPayload, processing crash/hang/disk-write diagnostics
When should I use metrickit?
Collect and analyze on-device performance metrics and crash diagnostics using MetricKit. Use when setting up MXMetricManager, handling MXMetricPayload or MXDiagnosticPayload, processing crash/hang/disk-write diagnostics
Is metrickit safe to install?
Review the Security Audits panel on this page before installing in production.