2026 Developer ToolsSystem Services
WWDC26 · 18 min · Developer Tools / System Services
Meet the new MetricKit
Find and fix performance problems faster than ever. Join us to explore how MetricKit equips you with vital performance metrics and actionable diagnostics to help you understand exactly where your app has opportunities for improvements. We’ll also cover how to intersect your app’s metrics and diagnostics by app state by using the StateReporting framework, providing you with the full picture to investigate optimizations in your app’s experience.
Watch at developer.apple.com ↗Chapters
Code shown on screen · 9 snippets
Receive metrics from MetricKit
// Receive metrics from MetricKit
import MetricKit
let manager = MetricManager()
for await report in manager.metricReports {
processReport(report)
} Send your metrics to the server
// Send your metrics to the server
import MetricKit
for await report in manager.metricReports {
let jsonData = try JSONEncoder().encode(report)
sendToServer(jsonData)
} Access your performance metrics
// Access your performance metrics
import MetricKit
for await report in manager.metricReports {
let intervalEntries = report.intervalEntries
let fullDayEntry = intervalEntries.fullDayEntry
for entry in intervalEntries {
let memoryMetrics = entry.values.filter { $0.metricGroup == .memory }
for metric in memoryMetrics {
switch metric {
case .peakMemory(let peak):
processPeakMemory(peak)
default: break
}
}
}
} Receive diagnostics
// Receive diagnostics
import MetricKit
let manager = MetricManager()
for await report in manager.diagnosticReports {
processReport(report)
} Send your diagnostic data to the server
// Send your diagnostic data to the server
import MetricKit
for await report in manager.diagnosticReports {
let jsonData = try JSONEncoder().encode(report)
sendToServer(jsonData)
} Access your diagnostic data
// Access your diagnostic data
import MetricKit
for await report in manager.diagnosticReports {
switch report.result {
case .crash(let crash):
let backtrace = crash.callStackTree
let reason = crash.terminationReason
let category = crash.terminationCategory
processCrash(backtrace: backtrace, reason: reason, category: category)
case .hang(let hang):
processHangDiagnostic(hang)
default: break
}
} Receive MetricKit data with states
// Receive MetricKit data with states
import MetricKit
import StateReporting
let domain = StateReportingDomain("com.metrickitsample.tabs")
let manager = MetricManager(enabledStateReportingDomains: [domain])
// Report transitions throughout the app
let reporter = StateReporter.reporter(for: domain.rawValue)
reporter.reportTransition(to: "Reports") Define custom structured types
// Define custom structured types
import StateReporting
struct ViewConfiguration {
let listSize: String
let isSorted: Bool
}
let reporter = StateReporter.reporter(
for: domain.rawValue,
stableMetadata: ViewConfiguration.self
)
reporter.reportTransition(
to: "Reports",
stableMetadata: ViewConfiguration(listSize: "large", isSorted: false)
) Send encoded metric reports to the server
// Send encoded metric reports to the server
import MetricKit
for await report in manager.metricReports {
let encoder = JSONEncoder()
let formatKey = MetricReport.encodingFormatKey
encoder.userInfo[formatKey] = MetricReport.EncodingFormat.byStateReportingDomain
let jsonData = try encoder.encode(report)
sendToServer(jsonData)
} Resources
Related sessions
-
27 min -
21 min