Skip to content

Monitoring Performance with MetricKit (SwiftUI)

A SwiftUI guide for coding agents. Also covers metrickit subscriber, mxmetricmanager, background termination reasons, crash diagnostics ios, oom exit tracking, performance dashboard ios.

MetricKit reports the performance data Xcode Organizer cannot fully explain, above all why the system terminated your app. Subscribe to MXMetricManager, receive metric and diagnostic payloads, and forward the numbers to your analytics backend.

Subscribe in the app delegate

Conform to MXMetricManagerSubscriber and add yourself at launch. The protocol has two optional callbacks: one for metrics, one for diagnostics.

final class AppDelegate: NSObject, UIApplicationDelegate, MXMetricManagerSubscriber {
  private var analytics: Analytics?

  func applicationDidFinishLaunching(_ application: UIApplication) {
    MXMetricManager.shared.add(self)
  }

  nonisolated func didReceive(_ payloads: [MXMetricPayload]) {
    for payload in payloads {
      if let exits = payload.applicationExitMetrics?.backgroundExitData {
        analytics?.logEvent("performance_abnormal_exit",
                            value: exits.cumulativeAbnormalExitCount.formatted())
        analytics?.logEvent("performance_cpu_exit",
                            value: exits.cumulativeCPUResourceLimitExitCount.formatted())
        analytics?.logEvent("performance_memory_exit",
                            value: exits.cumulativeMemoryPressureExitCount.formatted())
        analytics?.logEvent("performance_oom_exit",
                            value: exits.cumulativeMemoryResourceLimitExitCount.formatted())
      }
    }
  }

  nonisolated func didReceive(_ payloads: [MXDiagnosticPayload]) {
    for payload in payloads {
      payload.crashDiagnostics?.forEach { analytics?.logCrash($0) }
    }
  }
}

What the payloads carry

MXMetricPayload holds MXMetric subclasses such as applicationLaunchMetrics and applicationExitMetrics; the background exit data explains CPU-limit, memory-pressure, and out-of-memory kills. MXDiagnosticPayload holds MXDiagnostic subclasses such as crashDiagnostics and cpuExceptionDiagnostics. Both offer JSON and dictionary representations, so uploading to a custom endpoint is one call.

Delivery is on the system's schedule

Payloads usually arrive aggregated about once a day, sometimes more often, and never on a schedule you can rely on. Use each payload's timeStampBegin and timeStampEnd to know which window the numbers cover, and design the dashboard around windows, not events.

Use this guidance in your coding agent

Install the Better Design MCP once. Your agent then loads this page with one call.

get-swiftui-guide({ topic: "swiftui-monitoring-app-performance-with-metrickit" })
claude mcp add --scope user better-design --transport http https://better-design.com/api/mcp --header "Authorization: Bearer <YOUR_API_KEY>"
Browse related design systems