{"id":"6b382401-9f6c-46b3-8596-8c10a0ddb221","shortId":"CbjvUQ","kind":"skill","title":"metrickit","tagline":"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, or uplo","description":"# MetricKit\n\nCollect aggregated performance metrics and crash diagnostics from production\ndevices using MetricKit. The framework delivers daily metric payloads (CPU,\nmemory, launch time, hang rate, animation hitches, network usage) and\nimmediate diagnostic payloads (crashes, hangs, disk-write exceptions) with\nfull call-stack trees for triage.\n\n## Contents\n\n- [Subscriber Setup](#subscriber-setup)\n- [Receiving Metric Payloads](#receiving-metric-payloads)\n- [Receiving Diagnostic Payloads](#receiving-diagnostic-payloads)\n- [Key Metrics](#key-metrics)\n- [Call Stack Trees](#call-stack-trees)\n- [Custom Signpost Metrics](#custom-signpost-metrics)\n- [Exporting and Uploading Payloads](#exporting-and-uploading-payloads)\n- [Extended Launch Measurement](#extended-launch-measurement)\n- [Xcode Organizer Integration](#xcode-organizer-integration)\n- [Common Mistakes](#common-mistakes)\n- [Review Checklist](#review-checklist)\n- [References](#references)\n\n## Subscriber Setup\n\nRegister a subscriber as early as possible — ideally in\n`application(_:didFinishLaunchingWithOptions:)` or `App.init`. MetricKit\nstarts accumulating reports after the first access to `MXMetricManager.shared`.\n\n```swift\nimport MetricKit\n\nfinal class MetricsSubscriber: NSObject, MXMetricManagerSubscriber {\n    static let shared = MetricsSubscriber()\n\n    func subscribe() {\n        MXMetricManager.shared.add(self)\n    }\n\n    func unsubscribe() {\n        MXMetricManager.shared.remove(self)\n    }\n\n    func didReceive(_ payloads: [MXMetricPayload]) {\n        // Handle daily metrics\n    }\n\n    func didReceive(_ payloads: [MXDiagnosticPayload]) {\n        // Handle diagnostics (crashes, hangs, disk writes)\n    }\n}\n```\n\n### UIKit Registration\n\n```swift\nfunc application(\n    _ application: UIApplication,\n    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?\n) -> Bool {\n    MetricsSubscriber.shared.subscribe()\n    return true\n}\n```\n\n### SwiftUI Registration\n\n```swift\n@main\nstruct MyApp: App {\n    init() {\n        MetricsSubscriber.shared.subscribe()\n    }\n    var body: some Scene {\n        WindowGroup { ContentView() }\n    }\n}\n```\n\n## Receiving Metric Payloads\n\n`MXMetricPayload` arrives approximately once per 24 hours containing\naggregated metrics. The array may contain multiple payloads if prior\ndeliveries were missed.\n\n```swift\nfunc didReceive(_ payloads: [MXMetricPayload]) {\n    for payload in payloads {\n        let begin = payload.timeStampBegin\n        let end = payload.timeStampEnd\n        let version = payload.latestApplicationVersion\n\n        // Persist raw JSON before processing\n        let jsonData = payload.jsonRepresentation()\n        persistPayload(jsonData, from: begin, to: end)\n\n        processMetrics(payload)\n    }\n}\n```\n\n**Availability**: `MXMetricPayload` — iOS 13.0+, macOS 10.15+, visionOS 1.0+\n\n## Receiving Diagnostic Payloads\n\n`MXDiagnosticPayload` delivers crash, hang, CPU exception, disk-write, and\napp-launch diagnostics. On iOS 15+ and macOS 12+, diagnostics arrive\nimmediately rather than bundled with the daily report.\n\n```swift\nfunc didReceive(_ payloads: [MXDiagnosticPayload]) {\n    for payload in payloads {\n        let jsonData = payload.jsonRepresentation()\n        persistPayload(jsonData)\n\n        if let crashes = payload.crashDiagnostics {\n            for crash in crashes {\n                handleCrash(crash)\n            }\n        }\n        if let hangs = payload.hangDiagnostics {\n            for hang in hangs {\n                handleHang(hang)\n            }\n        }\n        if let diskWrites = payload.diskWriteExceptionDiagnostics {\n            for diskWrite in diskWrites {\n                handleDiskWrite(diskWrite)\n            }\n        }\n        if let cpuExceptions = payload.cpuExceptionDiagnostics {\n            for cpuException in cpuExceptions {\n                handleCPUException(cpuException)\n            }\n        }\n        if let launchDiags = payload.appLaunchDiagnostics {\n            for launchDiag in launchDiags {\n                handleSlowLaunch(launchDiag)\n            }\n        }\n    }\n}\n```\n\n**Availability**: `MXDiagnosticPayload` — iOS 14.0+, macOS 12.0+, visionOS 1.0+\n\n## Key Metrics\n\n### Launch Time — MXAppLaunchMetric\n\n```swift\nif let launch = payload.applicationLaunchMetrics {\n    let firstDraw = launch.histogrammedTimeToFirstDraw\n    let optimized = launch.histogrammedOptimizedTimeToFirstDraw\n    let resume = launch.histogrammedApplicationResumeTime\n    let extended = launch.histogrammedExtendedLaunch\n}\n```\n\n### Run Time — MXAppRunTimeMetric\n\n```swift\nif let runTime = payload.applicationTimeMetrics {\n    let fg = runTime.cumulativeForegroundTime    // Measurement<UnitDuration>\n    let bg = runTime.cumulativeBackgroundTime\n    let bgAudio = runTime.cumulativeBackgroundAudioTime\n    let bgLocation = runTime.cumulativeBackgroundLocationTime\n}\n```\n\n### CPU, Memory, and Responsiveness\n\n```swift\nif let cpu = payload.cpuMetrics {\n    let cpuTime = cpu.cumulativeCPUTime              // Measurement<UnitDuration>\n}\nif let memory = payload.memoryMetrics {\n    let peakMemory = memory.peakMemoryUsage           // Measurement<UnitInformationStorage>\n}\nif let responsiveness = payload.applicationResponsivenessMetrics {\n    let hangTime = responsiveness.histogrammedApplicationHangTime\n}\nif let animation = payload.animationMetrics {\n    let scrollHitchRate = animation.scrollHitchTimeRatio  // Measurement<Unit>\n}\n```\n\n### Network and Cellular\n\n```swift\nif let network = payload.networkTransferMetrics {\n    let wifiUp = network.cumulativeWifiUpload          // Measurement<UnitInformationStorage>\n    let wifiDown = network.cumulativeWifiDownload\n    let cellUp = network.cumulativeCellularUpload\n    let cellDown = network.cumulativeCellularDownload\n}\n```\n\n### App Exit Metrics\n\n```swift\nif let exits = payload.applicationExitMetrics {\n    let fg = exits.foregroundExitData\n    let bg = exits.backgroundExitData\n    // Inspect normal, abnormal, watchdog, memory, etc.\n}\n```\n\n## Call Stack Trees\n\n`MXCallStackTree` is attached to each diagnostic. Use `jsonRepresentation()` to extract frame data, then symbolicate with `atos` or by uploading dSYMs to your analytics service.\n\nSee [references/metrickit-patterns.md](references/metrickit-patterns.md) for crash/hang handling code and JSON structure details.\n\n**Availability**: `MXCallStackTree` — iOS 14.0+, macOS 12.0+, visionOS 1.0+\n\n## Custom Signpost Metrics\n\nUse `mxSignpost` with a MetricKit log handle to capture custom performance\nintervals. These appear in the daily `MXMetricPayload` under `signpostMetrics`.\n\n```swift\nlet metricLog = MXMetricManager.makeLogHandle(category: \"Networking\")\n```\n\nSee [references/metrickit-patterns.md](references/metrickit-patterns.md) for signpost emission patterns and reading custom metrics from payloads.\n\n## Exporting and Uploading Payloads\n\nBoth payload types provide `jsonRepresentation()` for serialization. Always persist raw JSON to disk before processing — the system delivers each payload once. Use `pastPayloads` and `pastDiagnosticPayloads` on launch to recover missed deliveries.\n\nSee [references/metrickit-patterns.md](references/metrickit-patterns.md) for export code and past payload retrieval.\n\n## Extended Launch Measurement\n\nTrack post-first-draw setup work as part of the launch metric:\n\n```swift\nlet taskID = MXLaunchTaskID(\"com.example.app.loadDatabase\")\nMXMetricManager.shared.extendLaunchMeasurement(forTaskID: taskID)\nawait database.load()\nMXMetricManager.shared.finishExtendedLaunchMeasurement(forTaskID: taskID)\n```\n\nExtended launch times appear under `histogrammedExtendedLaunch` in `MXAppLaunchMetric`.\n\n## Xcode Organizer Integration\n\nXcode Organizer shows aggregated MetricKit data across opted-in users. Use it for trend analysis alongside on-device collection routed to your own backend.\n\nSee [references/metrickit-patterns.md](references/metrickit-patterns.md) for Organizer tab details.\n\n## Common Mistakes\n\n### DON'T: Subscribe to MXMetricManager too late\n\nThe system may deliver pending payloads shortly after launch. Subscribing\nlate (e.g., in a view controller) risks missing them entirely.\n\n```swift\n// WRONG — subscribing in a view controller\noverride func viewDidLoad() {\n    super.viewDidLoad()\n    MXMetricManager.shared.add(self)\n}\n\n// CORRECT — subscribe in application(_:didFinishLaunchingWithOptions:)\nfunc application(\n    _ application: UIApplication,\n    didFinishLaunchingWithOptions opts: [UIApplication.LaunchOptionsKey: Any]?\n) -> Bool {\n    MXMetricManager.shared.add(metricsSubscriber)\n    return true\n}\n```\n\n### DON'T: Ignore MXDiagnosticPayload\n\nOnly handling `MXMetricPayload` means you miss crash, hang, and disk-write\ndiagnostics — the most actionable data MetricKit provides.\n\n```swift\n// WRONG — only implementing metric callback\nfunc didReceive(_ payloads: [MXMetricPayload]) { /* ... */ }\n\n// CORRECT — implement both callbacks\nfunc didReceive(_ payloads: [MXMetricPayload]) { /* ... */ }\nfunc didReceive(_ payloads: [MXDiagnosticPayload]) { /* ... */ }\n```\n\n### DON'T: Process payloads without persisting first\n\nThe system delivers each payload once. If your subscriber crashes during\nprocessing, the data is lost permanently.\n\n```swift\n// WRONG — process inline, crash loses data\nfunc didReceive(_ payloads: [MXDiagnosticPayload]) {\n    for p in payloads {\n        riskyProcessing(p)  // If this crashes, payload is gone\n    }\n}\n\n// CORRECT — persist raw JSON first, then process\nfunc didReceive(_ payloads: [MXDiagnosticPayload]) {\n    for p in payloads {\n        let json = p.jsonRepresentation()\n        try? json.write(to: localCacheURL())   // Safe on disk\n        Task.detached { self.processAsync(json) }\n    }\n}\n```\n\n### DON'T: Do heavy work synchronously in didReceive\n\nThe callback runs on an arbitrary thread. Blocking it with heavy processing\nor synchronous network calls delays delivery of subsequent payloads.\n\n```swift\n// WRONG — synchronous upload in callback\nfunc didReceive(_ payloads: [MXMetricPayload]) {\n    for p in payloads {\n        let data = p.jsonRepresentation()\n        URLSession.shared.uploadTask(with: request, from: data).resume()  // sync wait\n    }\n}\n\n// CORRECT — persist and dispatch async\nfunc didReceive(_ payloads: [MXMetricPayload]) {\n    for p in payloads {\n        let json = p.jsonRepresentation()\n        persistLocally(json)\n        Task.detached(priority: .utility) {\n            await self.uploadToBackend(json)\n        }\n    }\n}\n```\n\n### DON'T: Expect immediate data in development\n\nMetricKit aggregates data over 24-hour windows. Payloads do not arrive\nimmediately after instrumenting. Use Xcode Organizer or simulated payloads\nfor faster iteration during development.\n\n## Review Checklist\n\n- [ ] `MXMetricManager.shared.add(subscriber)` called in `application(_:didFinishLaunchingWithOptions:)` or `App.init`\n- [ ] Subscriber conforms to `MXMetricManagerSubscriber` and inherits `NSObject`\n- [ ] Both `didReceive(_: [MXMetricPayload])` and `didReceive(_: [MXDiagnosticPayload])` implemented\n- [ ] Raw `jsonRepresentation()` persisted to disk before processing\n- [ ] Heavy processing dispatched asynchronously off the callback thread\n- [ ] `MXCallStackTree` JSON uploaded with dSYMs for symbolication\n- [ ] Custom signpost metrics limited to critical code paths\n- [ ] `pastPayloads` and `pastDiagnosticPayloads` checked on launch for missed deliveries\n- [ ] Extended launch tasks call both `extendLaunchMeasurement` and `finishExtendedLaunchMeasurement`\n- [ ] Analytics backend accepts and stores MetricKit JSON format\n- [ ] Xcode Organizer reviewed for regression trends alongside on-device data\n\n## References\n\n- Extended patterns: [references/metrickit-patterns.md](references/metrickit-patterns.md)\n- [MetricKit framework](https://sosumi.ai/documentation/metrickit)\n- [MXMetricManager](https://sosumi.ai/documentation/metrickit/mxmetricmanager)\n- [MXMetricManagerSubscriber](https://sosumi.ai/documentation/metrickit/mxmetricmanagersubscriber)\n- [MXMetricPayload](https://sosumi.ai/documentation/metrickit/mxmetricpayload)\n- [MXDiagnosticPayload](https://sosumi.ai/documentation/metrickit/mxdiagnosticpayload)","tags":["metrickit","swift","ios","skills","dpearson2699","accessibility","agent-skills","ai-coding","apple","claude-code","codex-skills","cursor-skills"],"capabilities":["skill","source-dpearson2699","skill-metrickit","topic-accessibility","topic-agent-skills","topic-ai-coding","topic-apple","topic-claude-code","topic-codex-skills","topic-cursor-skills","topic-ios","topic-ios-development","topic-liquid-glass","topic-localization","topic-mapkit"],"categories":["swift-ios-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/dpearson2699/swift-ios-skills/metrickit","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add dpearson2699/swift-ios-skills","source_repo":"https://github.com/dpearson2699/swift-ios-skills","install_from":"skills.sh"}},"qualityScore":"0.684","qualityRationale":"deterministic score 0.68 from registry signals: · indexed on github topic:agent-skills · 468 github stars · SKILL.md body (12,128 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-04-22T00:53:43.671Z","embedding":null,"createdAt":"2026-04-18T22:01:05.927Z","updatedAt":"2026-04-22T00:53:43.671Z","lastSeenAt":"2026-04-22T00:53:43.671Z","tsv":"'/documentation/metrickit)':1134 '/documentation/metrickit/mxdiagnosticpayload)':1150 '/documentation/metrickit/mxmetricmanager)':1138 '/documentation/metrickit/mxmetricmanagersubscriber)':1142 '/documentation/metrickit/mxmetricpayload)':1146 '1.0':313,418,584 '10.15':311 '12':336 '12.0':416,582 '13.0':309 '14.0':414,580 '15':333 '24':256,1014 'abnorm':535 'accept':1108 'access':178 'accumul':173 'across':718 'action':824 'ad':29 'aggreg':37,259,715,1011 'alongsid':728,1120 'alway':638 'analysi':727 'analyt':564,1106 'analyz':4 'anim':60,492 'animation.scrollhitchtimeratio':496 'app':239,328,519 'app-launch':327 'app.init':170,1044 'appear':601,704 'applic':167,222,223,790,793,794,1041 'approxim':253 'arbitrari':938 'array':262 'arriv':252,338,1020 'async':983 'asynchron':1069 'ato':557 'attach':544 'avail':306,411,577 'await':696,1000 'backend':737,1107 'begin':282,301 'bg':454,531 'bgaudio':457 'bglocat':460 'block':940 'bodi':243 'bool':229,800 'bundl':342 'call':77,107,111,539,948,1039,1101 'call-stack':76 'call-stack-tre':110 'callback':833,841,934,959,1072 'captur':596 'categori':612 'celldown':517 'cellular':500 'cellup':514 'check':1092 'checklist':150,153,1036 'class':185 'code':572,667,1087 'collect':2,36,732 'com.example.app.loaddatabase':692 'common':144,147,745 'common-mistak':146 'conform':1046 'contain':258,264 'content':82 'contentview':247 'control':769,780 'correct':787,838,897,979 'cpu':54,321,462,469 'cpu.cumulativecputime':473 'cpuexcept':393,396,398,400 'cputim':472 'crash':11,41,68,214,319,363,366,368,370,815,866,878,893 'crash/hang':570 'crash/hang/disk-write':25 'critic':1086 'custom':30,114,118,585,597,623,1081 'custom-signpost-metr':117 'daili':51,206,345,604 'data':553,717,825,870,880,969,975,1007,1012,1124 'database.load':697 'delay':949 'deliv':50,318,648,757,859 'deliveri':269,661,950,1097 'detail':576,744 'develop':1009,1034 'devic':7,45,731,1123 'diagnost':12,26,42,66,96,100,213,315,330,337,547,821 'didfinishlaunchingwithopt':168,225,791,796,1042 'didrec':202,209,274,349,835,843,847,882,905,932,961,985,1053,1056 'disk':71,216,324,643,819,921,1063 'disk-writ':70,323,818 'diskwrit':383,386,388,390 'dispatch':982,1068 'draw':679 'dsym':561,1078 'e.g':765 'earli':162 'emiss':619 'end':285,303 'entir':773 'etc':538 'except':73,322 'exit':520,525 'exits.backgroundexitdata':532 'exits.foregroundexitdata':529 'expect':1005 'export':121,126,627,666 'exporting-and-uploading-payload':125 'extend':130,134,439,672,701,1098,1126 'extended-launch-measur':133 'extendlaunchmeasur':1103 'extract':551 'faster':1031 'fg':450,528 'final':184 'finishextendedlaunchmeasur':1105 'first':177,678,856,901 'firstdraw':430 'format':1113 'fortaskid':694,699 'frame':552 'framework':49,1131 'full':75 'func':193,197,201,208,221,273,348,782,792,834,842,846,881,904,960,984 'gone':896 'handl':20,205,212,571,594,810 'handlecpuexcept':399 'handlecrash':369 'handlediskwrit':389 'handlehang':379 'handleslowlaunch':409 'hang':58,69,215,320,373,376,378,380,816 'hangtim':488 'heavi':928,943,1066 'histogrammedextendedlaunch':706 'hitch':61 'hour':257,1015 'ideal':165 'ignor':807 'immedi':65,339,1006,1021 'implement':831,839,1058 'import':182 'inherit':1050 'init':240 'inlin':877 'inspect':533 'instrument':1023 'integr':139,143,711 'interv':599 'io':308,332,413,579 'iter':1032 'json':292,574,641,900,913,924,993,996,1002,1075,1112 'json.write':916 'jsondata':296,299,357,360 'jsonrepresent':549,635,1060 'key':102,105,419 'key-metr':104 'late':753,764 'launch':56,131,135,329,421,427,657,673,686,702,762,1094,1099 'launch.histogrammedapplicationresumetime':437 'launch.histogrammedextendedlaunch':440 'launch.histogrammedoptimizedtimetofirstdraw':434 'launch.histogrammedtimetofirstdraw':431 'launchdiag':403,406,408,410 'launchopt':226 'let':190,281,284,287,295,356,362,372,382,392,402,426,429,432,435,438,446,449,453,456,459,468,471,476,479,484,487,491,494,503,506,510,513,516,524,527,530,609,689,912,968,992 'limit':1084 'localcacheurl':918 'log':593 'lose':879 'lost':872 'maco':310,335,415,581 'main':236 'may':263,756 'mean':812 'measur':132,136,452,474,482,497,509,674 'memori':55,463,477,537 'memory.peakmemoryusage':481 'metric':9,32,39,52,89,93,103,106,116,120,207,249,260,420,521,587,624,687,832,1083 'metrickit':1,14,35,47,171,183,592,716,826,1010,1111,1130 'metriclog':610 'metricssubscrib':186,192,802 'metricssubscriber.shared.subscribe':230,241 'miss':271,660,771,814,1096 'mistak':145,148,746 'multipl':265 'mxapplaunchmetr':423,708 'mxappruntimemetr':443 'mxcallstacktre':28,542,578,1074 'mxdiagnosticpayload':23,211,317,351,412,808,849,884,907,1057,1147 'mxlaunchtaskid':691 'mxmetricmanag':19,751,1135 'mxmetricmanager.makeloghandle':611 'mxmetricmanager.shared':180 'mxmetricmanager.shared.add':195,785,801,1037 'mxmetricmanager.shared.extendlaunchmeasurement':693 'mxmetricmanager.shared.finishextendedlaunchmeasurement':698 'mxmetricmanager.shared.remove':199 'mxmetricmanagersubscrib':188,1048,1139 'mxmetricpayload':21,204,251,276,307,605,811,837,845,963,987,1054,1143 'mxsignpost':589 'myapp':238 'network':62,498,504,613,947 'network.cumulativecellulardownload':518 'network.cumulativecellularupload':515 'network.cumulativewifidownload':512 'network.cumulativewifiupload':508 'normal':534 'nsobject':187,1051 'on-devic':5,729,1121 'opt':720,797 'opted-in':719 'optim':433 'organ':138,142,710,713,742,1026,1115 'overrid':781 'p':886,890,909,965,989 'p.jsonrepresentation':914,970,994 'part':683 'past':669 'pastdiagnosticpayload':655,1091 'pastpayload':653,1089 'path':1088 'pattern':620,1127 'payload':53,67,90,94,97,101,124,129,203,210,250,266,275,278,280,305,316,350,353,355,626,630,632,650,670,759,836,844,848,853,861,883,888,894,906,911,953,962,967,986,991,1017,1029 'payload.animationmetrics':493 'payload.applaunchdiagnostics':404 'payload.applicationexitmetrics':526 'payload.applicationlaunchmetrics':428 'payload.applicationresponsivenessmetrics':486 'payload.applicationtimemetrics':448 'payload.cpuexceptiondiagnostics':394 'payload.cpumetrics':470 'payload.crashdiagnostics':364 'payload.diskwriteexceptiondiagnostics':384 'payload.hangdiagnostics':374 'payload.jsonrepresentation':297,358 'payload.latestapplicationversion':289 'payload.memorymetrics':478 'payload.networktransfermetrics':505 'payload.timestampbegin':283 'payload.timestampend':286 'peakmemori':480 'pend':758 'per':255 'perform':8,38,598 'perman':873 'persist':290,639,855,898,980,1061 'persistloc':995 'persistpayload':298,359 'possibl':164 'post':677 'post-first-draw':676 'prior':268 'prioriti':998 'process':24,294,645,852,868,876,903,944,1065,1067 'processmetr':304 'product':44 'provid':634,827 'rate':59 'rather':340 'raw':291,640,899,1059 'read':622 'receiv':88,92,95,99,248,314 'receiving-diagnostic-payload':98 'receiving-metric-payload':91 'recov':659 'refer':154,155,1125 'references/metrickit-patterns.md':567,568,615,616,663,664,739,740,1128,1129 'regist':158 'registr':219,234 'regress':1118 'report':174,346 'request':973 'respons':465,485 'responsiveness.histogrammedapplicationhangtime':489 'resum':436,976 'retriev':671 'return':231,803 'review':149,152,1035,1116 'review-checklist':151 'risk':770 'riskyprocess':889 'rout':733 'run':441,935 'runtim':447 'runtime.cumulativebackgroundaudiotime':458 'runtime.cumulativebackgroundlocationtime':461 'runtime.cumulativebackgroundtime':455 'runtime.cumulativeforegroundtime':451 'safe':919 'scene':245 'scrollhitchr':495 'see':566,614,662,738 'self':196,200,786 'self.processasync':923 'self.uploadtobackend':1001 'serial':637 'servic':565 'set':17 'setup':84,87,157,680 'share':191 'short':760 'show':714 'signpost':31,115,119,586,618,1082 'signpostmetr':607 'simul':1028 'skill' 'skill-metrickit' 'sosumi.ai':1133,1137,1141,1145,1149 'sosumi.ai/documentation/metrickit)':1132 'sosumi.ai/documentation/metrickit/mxdiagnosticpayload)':1148 'sosumi.ai/documentation/metrickit/mxmetricmanager)':1136 'sosumi.ai/documentation/metrickit/mxmetricmanagersubscriber)':1140 'sosumi.ai/documentation/metrickit/mxmetricpayload)':1144 'source-dpearson2699' 'stack':78,108,112,540 'start':172 'static':189 'store':1110 'struct':237 'structur':575 'subscrib':83,86,156,160,194,749,763,776,788,865,1038,1045 'subscriber-setup':85 'subsequ':952 'super.viewdidload':784 'swift':181,220,235,272,347,424,444,466,501,522,608,688,774,828,874,954 'swiftui':233 'symbol':555,1080 'sync':977 'synchron':930,946,956 'system':647,755,858 'tab':743 'task':1100 'task.detached':922,997 'taskid':690,695,700 'thread':939,1073 'time':57,422,442,703 'topic-accessibility' 'topic-agent-skills' 'topic-ai-coding' 'topic-apple' 'topic-claude-code' 'topic-codex-skills' 'topic-cursor-skills' 'topic-ios' 'topic-ios-development' 'topic-liquid-glass' 'topic-localization' 'topic-mapkit' 'track':675 'tree':79,109,113,541 'trend':726,1119 'tri':915 'triag':81 'true':232,804 'type':633 'uiapplic':224,795 'uiapplication.launchoptionskey':227,798 'uikit':218 'unsubscrib':198 'uplo':34 'upload':123,128,560,629,957,1076 'urlsession.shared.uploadtask':971 'usag':63 'use':13,15,46,548,588,652,723,1024 'user':722 'util':999 'var':242 'version':288 'via':27 'view':768,779 'viewdidload':783 'visiono':312,417,583 'wait':978 'watchdog':536 'wifidown':511 'wifiup':507 'window':1016 'windowgroup':246 'without':854 'work':681,929 'write':72,217,325,820 'wrong':775,829,875,955 'xcode':137,141,709,712,1025,1114 'xcode-organizer-integr':140","prices":[{"id":"86592296-8da3-4764-b093-36729da79748","listingId":"6b382401-9f6c-46b3-8596-8c10a0ddb221","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"dpearson2699","category":"swift-ios-skills","install_from":"skills.sh"},"createdAt":"2026-04-18T22:01:05.927Z"}],"sources":[{"listingId":"6b382401-9f6c-46b3-8596-8c10a0ddb221","source":"github","sourceId":"dpearson2699/swift-ios-skills/metrickit","sourceUrl":"https://github.com/dpearson2699/swift-ios-skills/tree/main/skills/metrickit","isPrimary":false,"firstSeenAt":"2026-04-18T22:01:05.927Z","lastSeenAt":"2026-04-22T00:53:43.671Z"}],"details":{"listingId":"6b382401-9f6c-46b3-8596-8c10a0ddb221","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"dpearson2699","slug":"metrickit","github":{"repo":"dpearson2699/swift-ios-skills","stars":468,"topics":["accessibility","agent-skills","ai-coding","apple","claude-code","codex-skills","cursor-skills","ios","ios-development","liquid-glass","localization","mapkit","networking","storekit","swift","swift-concurrency","swiftdata","swiftui","widgetkit","xcode"],"license":"other","html_url":"https://github.com/dpearson2699/swift-ios-skills","pushed_at":"2026-04-21T19:26:16Z","description":"Agent Skills for iOS 26+, Swift 6.3, SwiftUI, and modern Apple frameworks","skill_md_sha":"ff5adae5e30e188c697e2689fe9f047c4faef289","skill_md_path":"skills/metrickit/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/dpearson2699/swift-ios-skills/tree/main/skills/metrickit"},"layout":"multi","source":"github","category":"swift-ios-skills","frontmatter":{"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, or uploading telemetry to an analytics backend."},"skills_sh_url":"https://skills.sh/dpearson2699/swift-ios-skills/metrickit"},"updatedAt":"2026-04-22T00:53:43.671Z"}}