@mmerterden/multi-agent-pipeline 20.7.0 → 20.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/LICENSE +0 -10
- package/docs/facts.json +1 -1
- package/manifest.json +266 -267
- package/package.json +2 -2
- package/pipeline/scripts/_notices.mjs +1 -1
- package/pipeline/skills/.skill-manifest.json +68 -68
- package/pipeline/skills/shared/README.md +70 -70
- package/pipeline/skills/shared/external/alarmkit/SKILL.md +373 -381
- package/pipeline/skills/shared/external/alarmkit/evals/evals.json +23 -18
- package/pipeline/skills/shared/external/alarmkit/references/alarmkit-patterns.md +328 -378
- package/pipeline/skills/shared/external/app-clips/SKILL.md +260 -160
- package/pipeline/skills/shared/external/app-clips/evals/evals.json +27 -27
- package/pipeline/skills/shared/external/app-clips/references/data-handoff-notifications-location.md +150 -83
- package/pipeline/skills/shared/external/app-clips/references/routing-and-experiences.md +135 -83
- package/pipeline/skills/shared/external/app-clips/references/size-capabilities-and-promotion.md +143 -85
- package/pipeline/skills/shared/external/app-intents/SKILL.md +302 -304
- package/pipeline/skills/shared/external/app-intents/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/app-intents/references/appintents-advanced.md +594 -894
- package/pipeline/skills/shared/external/app-store-optimization/SKILL.md +339 -277
- package/pipeline/skills/shared/external/app-store-optimization/evals/evals.json +27 -23
- package/pipeline/skills/shared/external/app-store-optimization/references/keyword-research-methodology.md +105 -122
- package/pipeline/skills/shared/external/app-store-optimization/references/product-page-variants.md +143 -166
- package/pipeline/skills/shared/external/app-store-review/SKILL.md +307 -326
- package/pipeline/skills/shared/external/app-store-review/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/app-store-review/references/privacy-manifest.md +105 -67
- package/pipeline/skills/shared/external/app-store-review/references/review-checklists.md +114 -101
- package/pipeline/skills/shared/external/apple-on-device-ai/SKILL.md +333 -360
- package/pipeline/skills/shared/external/apple-on-device-ai/evals/evals.json +24 -27
- package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-conversion.md +215 -322
- package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-optimization.md +161 -256
- package/pipeline/skills/shared/external/apple-on-device-ai/references/foundation-models.md +277 -387
- package/pipeline/skills/shared/external/apple-on-device-ai/references/mlx-swift.md +196 -210
- package/pipeline/skills/shared/external/authentication/SKILL.md +265 -381
- package/pipeline/skills/shared/external/authentication/evals/evals.json +25 -25
- package/pipeline/skills/shared/external/authentication/references/keychain-biometric.md +133 -178
- package/pipeline/skills/shared/external/authentication/references/passkeys.md +111 -147
- package/pipeline/skills/shared/external/avkit/SKILL.md +267 -364
- package/pipeline/skills/shared/external/avkit/evals/evals.json +26 -26
- package/pipeline/skills/shared/external/avkit/references/avkit-patterns.md +375 -493
- package/pipeline/skills/shared/external/background-processing/SKILL.md +270 -382
- package/pipeline/skills/shared/external/background-processing/evals/evals.json +22 -22
- package/pipeline/skills/shared/external/background-processing/references/background-task-patterns.md +169 -317
- package/pipeline/skills/shared/external/callkit-voip/SKILL.md +290 -371
- package/pipeline/skills/shared/external/callkit-voip/evals/evals.json +24 -24
- package/pipeline/skills/shared/external/callkit-voip/references/callkit-patterns.md +175 -343
- package/pipeline/skills/shared/external/cloudkit-sync/SKILL.md +292 -381
- package/pipeline/skills/shared/external/cloudkit-sync/evals/evals.json +33 -30
- package/pipeline/skills/shared/external/cloudkit-sync/references/cloudkit-patterns.md +227 -355
- package/pipeline/skills/shared/external/contacts-framework/SKILL.md +197 -346
- package/pipeline/skills/shared/external/contacts-framework/evals/evals.json +19 -21
- package/pipeline/skills/shared/external/contacts-framework/references/contacts-patterns.md +169 -308
- package/pipeline/skills/shared/external/core-bluetooth/SKILL.md +226 -376
- package/pipeline/skills/shared/external/core-bluetooth/evals/evals.json +25 -22
- package/pipeline/skills/shared/external/core-bluetooth/references/ble-patterns.md +257 -337
- package/pipeline/skills/shared/external/core-data/SKILL.md +292 -368
- package/pipeline/skills/shared/external/core-data/evals/evals.json +30 -27
- package/pipeline/skills/shared/external/core-motion/SKILL.md +235 -324
- package/pipeline/skills/shared/external/core-motion/evals/evals.json +31 -27
- package/pipeline/skills/shared/external/core-motion/references/motion-patterns.md +210 -310
- package/pipeline/skills/shared/external/core-nfc/SKILL.md +292 -366
- package/pipeline/skills/shared/external/core-nfc/evals/evals.json +22 -24
- package/pipeline/skills/shared/external/core-nfc/references/nfc-patterns.md +233 -329
- package/pipeline/skills/shared/external/coreml/SKILL.md +323 -367
- package/pipeline/skills/shared/external/coreml/evals/evals.json +24 -21
- package/pipeline/skills/shared/external/coreml/references/coreml-swift-integration.md +562 -565
- package/pipeline/skills/shared/external/cryptokit/SKILL.md +253 -394
- package/pipeline/skills/shared/external/cryptokit/evals/evals.json +20 -18
- package/pipeline/skills/shared/external/cryptokit/references/cryptokit-patterns.md +299 -488
- package/pipeline/skills/shared/external/debugging-instruments/SKILL.md +270 -323
- package/pipeline/skills/shared/external/debugging-instruments/evals/evals.json +27 -30
- package/pipeline/skills/shared/external/debugging-instruments/references/instruments-guide.md +167 -315
- package/pipeline/skills/shared/external/debugging-instruments/references/lldb-patterns.md +140 -193
- package/pipeline/skills/shared/external/device-integrity/SKILL.md +230 -353
- package/pipeline/skills/shared/external/device-integrity/evals/evals.json +25 -21
- package/pipeline/skills/shared/external/device-integrity/references/device-integrity-patterns.md +159 -197
- package/pipeline/skills/shared/external/energykit/SKILL.md +225 -392
- package/pipeline/skills/shared/external/energykit/evals/evals.json +29 -28
- package/pipeline/skills/shared/external/energykit/references/energykit-patterns.md +174 -470
- package/pipeline/skills/shared/external/eventkit-calendar/SKILL.md +261 -383
- package/pipeline/skills/shared/external/eventkit-calendar/evals/evals.json +25 -22
- package/pipeline/skills/shared/external/eventkit-calendar/references/eventkit-patterns.md +165 -268
- package/pipeline/skills/shared/external/healthkit/SKILL.md +252 -303
- package/pipeline/skills/shared/external/healthkit/evals/evals.json +24 -23
- package/pipeline/skills/shared/external/healthkit/references/healthkit-patterns.md +369 -523
- package/pipeline/skills/shared/external/homekit-matter/SKILL.md +233 -348
- package/pipeline/skills/shared/external/homekit-matter/evals/evals.json +27 -22
- package/pipeline/skills/shared/external/homekit-matter/references/matter-commissioning.md +199 -305
- package/pipeline/skills/shared/external/ios-accessibility/SKILL.md +368 -340
- package/pipeline/skills/shared/external/ios-accessibility/evals/evals.json +28 -27
- package/pipeline/skills/shared/external/ios-accessibility/references/a11y-patterns.md +314 -260
- package/pipeline/skills/shared/external/ios-accessibility/references/media-accessibility.md +97 -67
- package/pipeline/skills/shared/external/ios-accessibility/references/nutrition-labels.md +165 -101
- package/pipeline/skills/shared/external/ios-localization/SKILL.md +258 -371
- package/pipeline/skills/shared/external/ios-localization/evals/evals.json +23 -23
- package/pipeline/skills/shared/external/ios-localization/references/formatstyle-locale.md +283 -491
- package/pipeline/skills/shared/external/ios-localization/references/string-catalogs.md +313 -440
- package/pipeline/skills/shared/external/ios-networking/SKILL.md +265 -341
- package/pipeline/skills/shared/external/ios-networking/evals/evals.json +24 -24
- package/pipeline/skills/shared/external/ios-networking/references/background-websocket.md +425 -652
- package/pipeline/skills/shared/external/ios-networking/references/file-storage-patterns.md +143 -285
- package/pipeline/skills/shared/external/ios-networking/references/lightweight-clients.md +93 -53
- package/pipeline/skills/shared/external/ios-networking/references/network-framework.md +231 -456
- package/pipeline/skills/shared/external/ios-networking/references/urlsession-patterns.md +517 -784
- package/pipeline/skills/shared/external/ios-simulator/SKILL.md +265 -393
- package/pipeline/skills/shared/external/ios-simulator/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/ios-simulator/references/simctl-commands.md +177 -270
- package/pipeline/skills/shared/external/live-activities/SKILL.md +318 -360
- package/pipeline/skills/shared/external/live-activities/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/live-activities/references/activitykit-patterns.md +478 -710
- package/pipeline/skills/shared/external/mapkit-location/SKILL.md +295 -267
- package/pipeline/skills/shared/external/mapkit-location/evals/evals.json +28 -24
- package/pipeline/skills/shared/external/mapkit-location/references/mapkit-corelocation-patterns.md +378 -532
- package/pipeline/skills/shared/external/mapkit-location/references/mapkit-patterns.md +397 -499
- package/pipeline/skills/shared/external/metrickit-diagnostics/SKILL.md +165 -348
- package/pipeline/skills/shared/external/metrickit-diagnostics/evals/evals.json +26 -23
- package/pipeline/skills/shared/external/metrickit-diagnostics/references/metrickit-patterns.md +123 -130
- package/pipeline/skills/shared/external/musickit-audio/SKILL.md +189 -315
- package/pipeline/skills/shared/external/musickit-audio/evals/evals.json +22 -21
- package/pipeline/skills/shared/external/musickit-audio/references/musickit-patterns.md +181 -270
- package/pipeline/skills/shared/external/natural-language/SKILL.md +188 -340
- package/pipeline/skills/shared/external/natural-language/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/natural-language/references/translation-patterns.md +171 -225
- package/pipeline/skills/shared/external/passkit-wallet/SKILL.md +258 -392
- package/pipeline/skills/shared/external/passkit-wallet/evals/evals.json +30 -29
- package/pipeline/skills/shared/external/passkit-wallet/references/wallet-passes.md +164 -231
- package/pipeline/skills/shared/external/pdfkit/SKILL.md +312 -344
- package/pipeline/skills/shared/external/pdfkit/evals/evals.json +19 -19
- package/pipeline/skills/shared/external/pdfkit/references/pdfkit-patterns.md +413 -624
- package/pipeline/skills/shared/external/pencilkit-drawing/SKILL.md +242 -358
- package/pipeline/skills/shared/external/pencilkit-drawing/evals/evals.json +25 -21
- package/pipeline/skills/shared/external/pencilkit-drawing/references/pencilkit-patterns.md +161 -226
- package/pipeline/skills/shared/external/permissionkit/SKILL.md +282 -400
- package/pipeline/skills/shared/external/permissionkit/evals/evals.json +27 -30
- package/pipeline/skills/shared/external/permissionkit/references/permissionkit-patterns.md +237 -350
- package/pipeline/skills/shared/external/photos-camera-media/SKILL.md +276 -325
- package/pipeline/skills/shared/external/photos-camera-media/references/av-playback.md +299 -545
- package/pipeline/skills/shared/external/photos-camera-media/references/camera-capture.md +344 -588
- package/pipeline/skills/shared/external/photos-camera-media/references/image-loading-caching.md +316 -660
- package/pipeline/skills/shared/external/photos-camera-media/references/photokit-patterns.md +270 -416
- package/pipeline/skills/shared/external/push-notifications/SKILL.md +312 -340
- package/pipeline/skills/shared/external/push-notifications/evals/evals.json +27 -26
- package/pipeline/skills/shared/external/push-notifications/references/notification-patterns.md +328 -485
- package/pipeline/skills/shared/external/push-notifications/references/rich-notifications.md +327 -560
- package/pipeline/skills/shared/external/realitykit-ar/SKILL.md +218 -410
- package/pipeline/skills/shared/external/realitykit-ar/evals/evals.json +24 -27
- package/pipeline/skills/shared/external/realitykit-ar/references/realitykit-patterns.md +221 -348
- package/pipeline/skills/shared/external/shareplay-activities/SKILL.md +222 -393
- package/pipeline/skills/shared/external/shareplay-activities/evals/evals.json +23 -24
- package/pipeline/skills/shared/external/shareplay-activities/references/shareplay-patterns.md +280 -420
- package/pipeline/skills/shared/external/speech-recognition/SKILL.md +217 -421
- package/pipeline/skills/shared/external/speech-recognition/evals/evals.json +23 -26
- package/pipeline/skills/shared/external/speech-recognition/references/speechanalyzer-patterns.md +133 -125
- package/pipeline/skills/shared/external/storekit/SKILL.md +228 -204
- package/pipeline/skills/shared/external/storekit/evals/evals.json +27 -24
- package/pipeline/skills/shared/external/storekit/references/app-review-guidelines.md +98 -109
- package/pipeline/skills/shared/external/storekit/references/core-patterns.md +298 -242
- package/pipeline/skills/shared/external/storekit/references/storekit-advanced.md +356 -649
- package/pipeline/skills/shared/external/swift-api-design-guidelines/SKILL.md +274 -399
- package/pipeline/skills/shared/external/swift-api-design-guidelines/evals/evals.json +22 -24
- package/pipeline/skills/shared/external/swift-api-design-guidelines/references/argument-labels-and-parameters.md +107 -108
- package/pipeline/skills/shared/external/swift-api-design-guidelines/references/conventions-and-special-rules.md +93 -165
- package/pipeline/skills/shared/external/swift-api-design-guidelines/references/naming-and-clarity.md +99 -137
- package/pipeline/skills/shared/external/swift-api-design-guidelines/references/side-effects-and-mutating-pairs.md +77 -120
- package/pipeline/skills/shared/external/swift-architecture/SKILL.md +334 -350
- package/pipeline/skills/shared/external/swift-architecture/evals/evals.json +22 -22
- package/pipeline/skills/shared/external/swift-charts/SKILL.md +208 -394
- package/pipeline/skills/shared/external/swift-charts/evals/evals.json +27 -30
- package/pipeline/skills/shared/external/swift-charts/references/charts-patterns.md +351 -762
- package/pipeline/skills/shared/external/swift-codable/SKILL.md +339 -343
- package/pipeline/skills/shared/external/swift-codable/evals/evals.json +20 -20
- package/pipeline/skills/shared/external/swift-concurrency/SKILL.md +303 -351
- package/pipeline/skills/shared/external/swift-concurrency/evals/evals.json +27 -24
- package/pipeline/skills/shared/external/swift-concurrency/references/approachable-concurrency.md +65 -80
- package/pipeline/skills/shared/external/swift-concurrency/references/async-algorithms.md +48 -84
- package/pipeline/skills/shared/external/swift-concurrency/references/bridging-interop.md +134 -79
- package/pipeline/skills/shared/external/swift-concurrency/references/concurrency-patterns.md +145 -167
- package/pipeline/skills/shared/external/swift-concurrency/references/diagnostics.md +62 -50
- package/pipeline/skills/shared/external/swift-concurrency/references/swiftui-concurrency.md +92 -121
- package/pipeline/skills/shared/external/swift-concurrency/references/synchronization-primitives.md +177 -241
- package/pipeline/skills/shared/external/swift-formatstyle/SKILL.md +258 -234
- package/pipeline/skills/shared/external/swift-language/SKILL.md +342 -382
- package/pipeline/skills/shared/external/swift-language/evals/evals.json +24 -27
- package/pipeline/skills/shared/external/swift-language/references/swift-attributes-interop.md +79 -56
- package/pipeline/skills/shared/external/swift-language/references/swift-patterns-extended.md +297 -340
- package/pipeline/skills/shared/external/swift-security/SKILL.md +180 -161
- package/pipeline/skills/shared/external/swift-security/evals/evals.json +25 -25
- package/pipeline/skills/shared/external/swift-security/references/biometric-authentication.md +314 -469
- package/pipeline/skills/shared/external/swift-security/references/certificate-trust.md +408 -476
- package/pipeline/skills/shared/external/swift-security/references/common-anti-patterns.md +260 -530
- package/pipeline/skills/shared/external/swift-security/references/compliance-owasp-mapping.md +270 -477
- package/pipeline/skills/shared/external/swift-security/references/credential-storage-patterns.md +573 -571
- package/pipeline/skills/shared/external/swift-security/references/cryptokit-public-key.md +370 -441
- package/pipeline/skills/shared/external/swift-security/references/cryptokit-symmetric.md +332 -433
- package/pipeline/skills/shared/external/swift-security/references/keychain-access-control.md +346 -468
- package/pipeline/skills/shared/external/swift-security/references/keychain-fundamentals.md +352 -472
- package/pipeline/skills/shared/external/swift-security/references/keychain-item-classes.md +431 -432
- package/pipeline/skills/shared/external/swift-security/references/keychain-sharing.md +328 -425
- package/pipeline/skills/shared/external/swift-security/references/migration-legacy-stores.md +341 -579
- package/pipeline/skills/shared/external/swift-security/references/secure-enclave.md +396 -457
- package/pipeline/skills/shared/external/swift-security/references/testing-security-code.md +354 -614
- package/pipeline/skills/shared/external/swift-testing/SKILL.md +188 -175
- package/pipeline/skills/shared/external/swift-testing/evals/evals.json +26 -24
- package/pipeline/skills/shared/external/swift-testing/references/testing-advanced.md +80 -84
- package/pipeline/skills/shared/external/swift-testing/references/testing-patterns.md +317 -433
- package/pipeline/skills/shared/external/swiftdata/SKILL.md +392 -256
- package/pipeline/skills/shared/external/swiftdata/evals/evals.json +24 -24
- package/pipeline/skills/shared/external/swiftdata/references/core-data-coexistence.md +206 -402
- package/pipeline/skills/shared/external/swiftdata/references/indexing.md +59 -52
- package/pipeline/skills/shared/external/swiftdata/references/predicate-pitfalls.md +57 -33
- package/pipeline/skills/shared/external/swiftdata/references/swiftdata-advanced.md +354 -747
- package/pipeline/skills/shared/external/swiftdata/references/swiftdata-queries.md +300 -508
- package/pipeline/skills/shared/external/swiftlint/SKILL.md +175 -226
- package/pipeline/skills/shared/external/swiftlint/references/adoption-and-configuration.md +141 -208
- package/pipeline/skills/shared/external/swiftlint/references/custom-rules-and-analyze.md +100 -109
- package/pipeline/skills/shared/external/swiftlint/references/plugins-run-scripts-and-integrations.md +159 -179
- package/pipeline/skills/shared/external/swiftlint/references/rule-reference.md +383 -18
- package/pipeline/skills/shared/external/swiftlint/references/rules-suppressions-and-baselines.md +143 -229
- package/pipeline/skills/shared/external/swiftui-animation/SKILL.md +283 -366
- package/pipeline/skills/shared/external/swiftui-animation/references/animation-advanced.md +396 -608
- package/pipeline/skills/shared/external/swiftui-animation/references/core-animation-bridge.md +336 -385
- package/pipeline/skills/shared/external/swiftui-gestures/SKILL.md +239 -349
- package/pipeline/skills/shared/external/swiftui-gestures/references/gesture-patterns.md +228 -310
- package/pipeline/skills/shared/external/swiftui-layout-components/SKILL.md +260 -249
- package/pipeline/skills/shared/external/swiftui-layout-components/references/form.md +92 -74
- package/pipeline/skills/shared/external/swiftui-layout-components/references/grids.md +112 -177
- package/pipeline/skills/shared/external/swiftui-layout-components/references/list.md +61 -64
- package/pipeline/skills/shared/external/swiftui-layout-components/references/scrollview.md +94 -134
- package/pipeline/skills/shared/external/swiftui-liquid-glass/SKILL.md +193 -225
- package/pipeline/skills/shared/external/swiftui-liquid-glass/references/liquid-glass.md +173 -327
- package/pipeline/skills/shared/external/swiftui-navigation/SKILL.md +193 -168
- package/pipeline/skills/shared/external/swiftui-navigation/references/deeplinks.md +127 -150
- package/pipeline/skills/shared/external/swiftui-navigation/references/navigationstack.md +132 -133
- package/pipeline/skills/shared/external/swiftui-navigation/references/sheets.md +152 -117
- package/pipeline/skills/shared/external/swiftui-navigation/references/tabview.md +106 -140
- package/pipeline/skills/shared/external/swiftui-patterns/SKILL.md +316 -252
- package/pipeline/skills/shared/external/swiftui-patterns/references/architecture-patterns.md +341 -332
- package/pipeline/skills/shared/external/swiftui-patterns/references/deprecated-migration.md +547 -854
- package/pipeline/skills/shared/external/swiftui-patterns/references/design-polish.md +485 -537
- package/pipeline/skills/shared/external/swiftui-patterns/references/platform-and-sharing.md +417 -499
- package/pipeline/skills/shared/external/swiftui-performance/SKILL.md +213 -376
- package/pipeline/skills/shared/external/swiftui-performance/references/demystify-swiftui-performance-wwdc23.md +86 -175
- package/pipeline/skills/shared/external/swiftui-performance/references/optimizing-swiftui-performance-instruments.md +89 -195
- package/pipeline/skills/shared/external/swiftui-performance/references/understanding-hangs-in-your-app.md +95 -182
- package/pipeline/skills/shared/external/swiftui-performance/references/understanding-improving-swiftui-performance.md +71 -149
- package/pipeline/skills/shared/external/swiftui-performance/references/wwdc-session-sources.md +21 -27
- package/pipeline/skills/shared/external/swiftui-uikit-interop/SKILL.md +303 -295
- package/pipeline/skills/shared/external/swiftui-uikit-interop/references/hosting-migration.md +204 -387
- package/pipeline/skills/shared/external/swiftui-uikit-interop/references/representable-recipes.md +469 -683
- package/pipeline/skills/shared/external/swiftui-webkit/SKILL.md +140 -186
- package/pipeline/skills/shared/external/swiftui-webkit/references/loading-and-observation.md +75 -86
- package/pipeline/skills/shared/external/swiftui-webkit/references/local-content-and-custom-schemes.md +63 -60
- package/pipeline/skills/shared/external/swiftui-webkit/references/migration-and-fallbacks.md +69 -137
- package/pipeline/skills/shared/external/swiftui-webkit/references/navigation-and-javascript.md +95 -67
- package/pipeline/skills/shared/external/tipkit/SKILL.md +220 -335
- package/pipeline/skills/shared/external/tipkit/references/tipkit-patterns.md +356 -494
- package/pipeline/skills/shared/external/vision-framework/SKILL.md +260 -375
- package/pipeline/skills/shared/external/vision-framework/references/vision-requests.md +393 -515
- package/pipeline/skills/shared/external/vision-framework/references/visionkit-scanner.md +363 -539
- package/pipeline/skills/shared/external/weatherkit/SKILL.md +152 -310
- package/pipeline/skills/shared/external/weatherkit/references/weatherkit-patterns.md +288 -407
- package/pipeline/skills/shared/external/widgetkit/SKILL.md +216 -288
- package/pipeline/skills/shared/external/widgetkit/references/widgetkit-advanced.md +414 -719
- package/pipeline/skills/shared/external/NOTICE-swift-ios-skills.md +0 -39
|
@@ -1,454 +1,401 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: debugging-instruments
|
|
3
|
-
description: "
|
|
3
|
+
description: "Xcode debugging and profiling: LLDB, Memory Graph Debugger, Instruments, crashes, leaks and retain cycles, main-thread hangs, slow rendering, build failures, CPU, memory, energy and network profiling. Use when debugging or profiling an iOS app."
|
|
4
4
|
metadata:
|
|
5
|
-
source:
|
|
5
|
+
source: multi-agent-pipeline
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Debugging and Instruments
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
Baseline: Xcode 26 with iOS 26 devices and simulators. The LLDB commands and
|
|
11
|
+
most Instruments templates are much older and work the same on earlier
|
|
12
|
+
releases.
|
|
11
13
|
|
|
12
|
-
|
|
14
|
+
Covers: LLDB breakpoints, expressions and watchpoints, Malloc Stack Logging,
|
|
15
|
+
Instruments templates, `xctrace`, signposts, and build failures from the
|
|
16
|
+
compiler, SwiftPM or the linker.
|
|
13
17
|
|
|
14
|
-
|
|
15
|
-
- [Memory Debugging](#memory-debugging)
|
|
16
|
-
- [Hang Diagnostics](#hang-diagnostics)
|
|
17
|
-
- [Build Failure Triage](#build-failure-triage)
|
|
18
|
-
- [Instruments Overview](#instruments-overview)
|
|
19
|
-
- [Common Mistakes](#common-mistakes)
|
|
20
|
-
- [Review Checklist](#review-checklist)
|
|
21
|
-
- [References](#references)
|
|
18
|
+
Hand these to their own skills and keep the answer here to a short pointer:
|
|
22
19
|
|
|
23
|
-
|
|
20
|
+
| Topic | Skill |
|
|
21
|
+
|-------|-------|
|
|
22
|
+
| Rewriting SwiftUI views once a trace shows the cost | `swiftui-performance` |
|
|
23
|
+
| `MXMetricManager` subscribers, `MXDiagnosticPayload`, `MXHangDiagnostic` | `metrickit-diagnostics` |
|
|
24
|
+
| Organising benchmarks and perf tests in a test suite | `swift-testing` |
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
Deeper material: [full LLDB notes](references/lldb-patterns.md) and a
|
|
27
|
+
[template-by-template Instruments guide](references/instruments-guide.md).
|
|
26
28
|
|
|
27
|
-
|
|
28
|
-
(lldb) po myObject # Print object description (calls debugDescription)
|
|
29
|
-
(lldb) p myInt # Print with type info (uses LLDB formatter)
|
|
30
|
-
(lldb) v myLocal # Frame variable - fast, no code execution
|
|
31
|
-
(lldb) bt # Backtrace current thread
|
|
32
|
-
(lldb) bt all # Backtrace all threads
|
|
33
|
-
(lldb) frame select 3 # Jump to frame #3 in the backtrace
|
|
34
|
-
(lldb) thread list # List all threads and their states
|
|
35
|
-
(lldb) thread select 4 # Switch to thread #4
|
|
36
|
-
```
|
|
29
|
+
## LLDB
|
|
37
30
|
|
|
38
|
-
|
|
39
|
-
execute code and cannot trigger side effects.
|
|
31
|
+
### Everyday commands
|
|
40
32
|
|
|
41
|
-
|
|
33
|
+
| Command | Effect |
|
|
34
|
+
|---------|--------|
|
|
35
|
+
| `v total` | Reads a frame variable straight from memory. Fast, runs no code. |
|
|
36
|
+
| `p total` | Evaluates an expression and prints it with type info through the LLDB formatter. |
|
|
37
|
+
| `po order` | Evaluates an expression and prints the object description (`debugDescription`). |
|
|
38
|
+
| `bt` / `bt all` | Backtrace of the current thread / of every thread. |
|
|
39
|
+
| `frame select 3` | Moves to frame 3 of the backtrace. |
|
|
40
|
+
| `thread list` / `thread select 2` | Lists threads with their state / switches to thread 2. |
|
|
41
|
+
|
|
42
|
+
Reach for `v` first when all you need is a local value. It executes nothing in
|
|
43
|
+
the target process, so it cannot trigger getters, locks or other side effects.
|
|
44
|
+
|
|
45
|
+
### Breakpoints
|
|
42
46
|
|
|
43
47
|
```text
|
|
44
|
-
(lldb) br set -f
|
|
45
|
-
(lldb) br set -n
|
|
46
|
-
(lldb) br set -S
|
|
47
|
-
(lldb) br modify 1 -c "count >
|
|
48
|
-
(lldb) br modify
|
|
49
|
-
(lldb) br command add 1
|
|
50
|
-
> po
|
|
48
|
+
(lldb) br set -f CartView.swift -l 88 # file and line
|
|
49
|
+
(lldb) br set -n applicationDidBecomeActive # function name
|
|
50
|
+
(lldb) br set -S setObject:forKey: # Objective-C selector
|
|
51
|
+
(lldb) br modify 1 -c "lineItems.count > 20" # add a condition
|
|
52
|
+
(lldb) br modify -G true 1 # print, then carry on
|
|
53
|
+
(lldb) br command add 1
|
|
54
|
+
> po lineItems.count
|
|
51
55
|
> continue
|
|
52
56
|
> DONE
|
|
53
|
-
(lldb) br disable 1
|
|
54
|
-
(lldb) br delete 1
|
|
57
|
+
(lldb) br disable 1 # keep it, but inactive
|
|
58
|
+
(lldb) br delete 1 # remove it
|
|
55
59
|
```
|
|
56
60
|
|
|
57
|
-
|
|
61
|
+
A breakpoint with commands plus `--auto-continue true` behaves as a logpoint.
|
|
62
|
+
|
|
63
|
+
### Evaluating and changing state
|
|
58
64
|
|
|
59
65
|
```text
|
|
60
|
-
(lldb) expr
|
|
61
|
-
(lldb)
|
|
62
|
-
(lldb)
|
|
63
|
-
(lldb)
|
|
66
|
+
(lldb) expr lineItems.count
|
|
67
|
+
(lldb) expression -l swift -- import UIKit
|
|
68
|
+
(lldb) expression -l swift -- self.checkoutButton.isEnabled = false
|
|
69
|
+
(lldb) expression -l objc -- (void)[CATransaction flush]
|
|
64
70
|
```
|
|
65
71
|
|
|
66
|
-
|
|
67
|
-
|
|
72
|
+
The process is paused, so UIKit will not redraw on its own. After changing a
|
|
73
|
+
view property from the debugger, flush the pending `CATransaction` to see the
|
|
74
|
+
change on screen without resuming.
|
|
68
75
|
|
|
69
76
|
### Watchpoints
|
|
70
77
|
|
|
71
78
|
```text
|
|
72
|
-
(lldb) w set v self.
|
|
73
|
-
(lldb) w set v self.
|
|
74
|
-
(lldb)
|
|
75
|
-
(lldb) w list
|
|
76
|
-
(lldb) w delete 1
|
|
79
|
+
(lldb) w set v self.balance # stop on write
|
|
80
|
+
(lldb) w set v self.balance -w read # stop on read
|
|
81
|
+
(lldb) watchpoint modify -c "self.balance < 0" 1 # only when it goes negative
|
|
82
|
+
(lldb) w list
|
|
83
|
+
(lldb) w delete 1
|
|
77
84
|
```
|
|
78
85
|
|
|
79
|
-
Watchpoints
|
|
80
|
-
|
|
81
|
-
the
|
|
86
|
+
Watchpoints use hardware debug registers, so only about four can be active at
|
|
87
|
+
once on ARM. They answer "who changed this value?": the debugger stops on the
|
|
88
|
+
exact line that performed the write.
|
|
82
89
|
|
|
83
|
-
### Symbolic
|
|
90
|
+
### Symbolic breakpoints
|
|
84
91
|
|
|
85
|
-
|
|
86
|
-
or system code
|
|
92
|
+
A symbolic breakpoint names a symbol rather than a file, which is how you stop
|
|
93
|
+
inside framework or system code whose source you do not have.
|
|
87
94
|
|
|
88
95
|
```text
|
|
89
|
-
(lldb) br set -n "UIViewController.
|
|
90
|
-
(lldb) br set -r ".*
|
|
91
|
-
(lldb) br set -n malloc_error_break
|
|
92
|
-
(lldb)
|
|
96
|
+
(lldb) br set -n "UIViewController.viewWillAppear"
|
|
97
|
+
(lldb) br set -r ".*paymentFailed.*" # regex over symbol names
|
|
98
|
+
(lldb) br set -n malloc_error_break # heap corruption
|
|
99
|
+
(lldb) breakpoint set --name UIViewAlertForUnsatisfiableConstraints
|
|
93
100
|
```
|
|
94
101
|
|
|
95
|
-
In Xcode,
|
|
96
|
-
|
|
102
|
+
In Xcode, open the Breakpoint Navigator, press +, choose Symbolic Breakpoint
|
|
103
|
+
and enter a symbol such as `swift_willThrow` or `-[UIView layoutSubviews]`.
|
|
97
104
|
|
|
98
|
-
## Memory
|
|
105
|
+
## Memory
|
|
99
106
|
|
|
100
|
-
### Memory Graph Debugger
|
|
107
|
+
### Memory Graph Debugger
|
|
101
108
|
|
|
102
|
-
1. Run the
|
|
103
|
-
2. Reproduce the suspected leak
|
|
104
|
-
3.
|
|
105
|
-
4.
|
|
106
|
-
5. Select
|
|
109
|
+
1. Run the Debug configuration.
|
|
110
|
+
2. Reproduce the suspected leak, for example open a screen and close it again.
|
|
111
|
+
3. Click the Memory Graph button in the debug bar.
|
|
112
|
+
4. Objects flagged with a purple warning icon are leaks.
|
|
113
|
+
5. Select one to see what references it and, with stack logging on, where it
|
|
114
|
+
was allocated.
|
|
107
115
|
|
|
108
|
-
|
|
109
|
-
the
|
|
116
|
+
Turn on Malloc Stack Logging (Scheme > Run > Diagnostics) before launching;
|
|
117
|
+
without it the graph shows ownership but no allocation backtrace.
|
|
110
118
|
|
|
111
|
-
###
|
|
112
|
-
|
|
113
|
-
**Closure capturing self strongly:**
|
|
119
|
+
### Retain cycles that come up again and again
|
|
114
120
|
|
|
115
121
|
```swift
|
|
116
|
-
|
|
117
|
-
class
|
|
118
|
-
var
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
122
|
+
@MainActor
|
|
123
|
+
final class UploadMonitor {
|
|
124
|
+
var onProgress: ((Double) -> Void)?
|
|
125
|
+
private var ticker: Timer?
|
|
126
|
+
private(set) var fraction = 0.0
|
|
127
|
+
|
|
128
|
+
func attach() {
|
|
129
|
+
onProgress = { [weak self] value in
|
|
130
|
+
self?.fraction = value
|
|
123
131
|
}
|
|
124
132
|
}
|
|
125
|
-
}
|
|
126
133
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
134
|
+
func start() {
|
|
135
|
+
ticker = Timer.scheduledTimer(withTimeInterval: 2, repeats: true) { [weak self] _ in
|
|
136
|
+
MainActor.assumeIsolated { self?.poll() }
|
|
137
|
+
}
|
|
131
138
|
}
|
|
132
|
-
}
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
**Strong delegate reference:**
|
|
136
139
|
|
|
137
|
-
|
|
138
|
-
// LEAK - strong delegate creates a cycle
|
|
139
|
-
protocol DataDelegate: AnyObject {
|
|
140
|
-
func didUpdate()
|
|
140
|
+
private func poll() {}
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
-
|
|
144
|
-
|
|
143
|
+
protocol UploadQueueDelegate: AnyObject {
|
|
144
|
+
func queueDidDrain(_ queue: UploadQueue)
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
weak var delegate: DataDelegate?
|
|
147
|
+
final class UploadQueue {
|
|
148
|
+
weak var delegate: UploadQueueDelegate?
|
|
150
149
|
}
|
|
151
150
|
```
|
|
152
151
|
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
complete picture.
|
|
176
|
-
- Filter by your app's module name to exclude system allocations.
|
|
177
|
-
|
|
178
|
-
For leak or memory-growth triage, pair the tools: use Allocations **Mark
|
|
179
|
-
Generation** before and after the reproduction step to prove retained growth,
|
|
180
|
-
then use Memory Graph Debugger to inspect object ownership and Malloc Stack
|
|
181
|
-
Logging to recover allocation call stacks.
|
|
152
|
+
- A stored closure that captures `self` strongly keeps its owner alive. Capture
|
|
153
|
+
`[weak self]` and call through `self?`.
|
|
154
|
+
- A strong delegate reference closes a loop. Constrain the protocol to
|
|
155
|
+
`AnyObject` and store the property as `weak var`.
|
|
156
|
+
- `Timer.scheduledTimer(timeInterval:target:selector:userInfo:repeats:)`
|
|
157
|
+
retains its target. Use the block API, `scheduledTimer(withTimeInterval:repeats:)`,
|
|
158
|
+
with `[weak self]`, and invalidate it when done. The block is `@Sendable`, so
|
|
159
|
+
on a main-actor class it reaches `self` through `MainActor.assumeIsolated`; a
|
|
160
|
+
timer scheduled from the main thread fires on the main run loop.
|
|
161
|
+
|
|
162
|
+
### Allocations and Leaks
|
|
163
|
+
|
|
164
|
+
- **Allocations** shows memory over time and object lifetimes. Use Mark
|
|
165
|
+
Generation before and after an action (open and close a screen) to isolate
|
|
166
|
+
what that action left behind.
|
|
167
|
+
- **Leaks** finds allocations nothing points to any more, including cycles that
|
|
168
|
+
have become unreachable. Record it alongside Allocations for the full picture.
|
|
169
|
+
- Filter the detail view by your module name to hide system allocations.
|
|
170
|
+
|
|
171
|
+
Triage recipe for a leak or steady growth: mark a generation before and after
|
|
172
|
+
the repro to prove memory is retained, open the Memory Graph Debugger to see
|
|
173
|
+
who owns it, and keep Malloc Stack Logging on for the allocation call stacks.
|
|
182
174
|
|
|
183
175
|
### Malloc Stack Logging
|
|
184
176
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
177
|
+
In the scheme editor, open Run, then the Diagnostics tab, and tick Malloc
|
|
178
|
+
Stack Logging. The recorded
|
|
179
|
+
allocation backtraces feed the Memory Graph Debugger, the Allocations
|
|
180
|
+
instrument and exported `.memgraph` files. Export a graph from Xcode (File >
|
|
181
|
+
Export Memory Graph) or Instruments and inspect it from Terminal:
|
|
188
182
|
|
|
189
183
|
```bash
|
|
190
|
-
|
|
191
|
-
leaks MyApp.memgraph
|
|
184
|
+
leaks Checkout.memgraph
|
|
192
185
|
```
|
|
193
186
|
|
|
194
|
-
##
|
|
187
|
+
## Hangs
|
|
188
|
+
|
|
189
|
+
### Thresholds and detection
|
|
195
190
|
|
|
196
|
-
|
|
191
|
+
For a discrete interaction such as a tap, a delay below roughly 100 ms goes
|
|
192
|
+
unnoticed, while a few hundred milliseconds already makes the app feel stuck.
|
|
193
|
+
Apple's tools usually start reporting once the main run loop stays busy for
|
|
194
|
+
more than 250 ms. Keep those two numbers apart: the tool threshold is not the
|
|
195
|
+
point where users start to notice.
|
|
197
196
|
|
|
198
|
-
|
|
199
|
-
hundred milliseconds can make an app feel unresponsive. Apple developer tools
|
|
200
|
-
typically start reporting main-run-loop busy periods over 250 ms. Common
|
|
201
|
-
detection tools:
|
|
197
|
+
Tools, from development to production:
|
|
202
198
|
|
|
203
|
-
-
|
|
204
|
-
-
|
|
205
|
-
-
|
|
206
|
-
|
|
207
|
-
-
|
|
208
|
-
-
|
|
209
|
-
|
|
199
|
+
- Thread Checker (Scheme > Diagnostics) flags UI calls made off the main thread.
|
|
200
|
+
- Thread Performance Checker flags priority inversions during a debug session.
|
|
201
|
+
- Hang Detection under Developer settings on the device reports hangs as you
|
|
202
|
+
use the app.
|
|
203
|
+
- Time Profiler, CPU Profiler and Hitches profile a hang you can reproduce.
|
|
204
|
+
- `os_signpost` and `OSSignposter` put your own intervals on the Instruments
|
|
205
|
+
timeline.
|
|
206
|
+
- MetricKit's `MXHangDiagnostic` catches hangs in the field; see
|
|
207
|
+
`metrickit-diagnostics`.
|
|
210
208
|
|
|
211
209
|
```swift
|
|
212
210
|
import os
|
|
213
211
|
|
|
214
|
-
let
|
|
212
|
+
let tripSignposts = OSSignposter(subsystem: "app.atlas.trips", category: "Sync")
|
|
215
213
|
|
|
216
|
-
func
|
|
217
|
-
let state =
|
|
218
|
-
let
|
|
219
|
-
|
|
220
|
-
|
|
214
|
+
func refreshTrips(from client: TripClient, into store: TripStore) async throws {
|
|
215
|
+
let state = tripSignposts.beginInterval("fetchTrips")
|
|
216
|
+
let trips = try await client.trips()
|
|
217
|
+
tripSignposts.endInterval("fetchTrips", state)
|
|
218
|
+
store.merge(trips)
|
|
221
219
|
}
|
|
222
220
|
```
|
|
223
221
|
|
|
224
|
-
###
|
|
222
|
+
### Time Profiler in five steps
|
|
225
223
|
|
|
226
|
-
1. Product > Profile (Cmd+I)
|
|
227
|
-
2.
|
|
228
|
-
3.
|
|
229
|
-
4.
|
|
230
|
-
5.
|
|
231
|
-
6. Double-click a heavy frame to jump to source.
|
|
224
|
+
1. Product > Profile (Cmd+I).
|
|
225
|
+
2. Pick Time Profiler, start recording, then perform the sluggish action.
|
|
226
|
+
3. Look at the main thread and sort by Weight to find the hot path.
|
|
227
|
+
4. Turn on Hide System Libraries to keep only your code.
|
|
228
|
+
5. Double-click an expensive frame to open the matching source line.
|
|
232
229
|
|
|
233
|
-
###
|
|
230
|
+
### Usual causes
|
|
234
231
|
|
|
235
232
|
| Cause | Symptom | Fix |
|
|
236
233
|
|-------|---------|-----|
|
|
237
|
-
| Synchronous I/O on main
|
|
238
|
-
| Lock contention | Main
|
|
239
|
-
| Layout
|
|
240
|
-
| JSON
|
|
241
|
-
| Synchronous image decoding |
|
|
234
|
+
| Synchronous file or network I/O on main | UI freezes while data loads | Do the work in a `Task` or a background actor |
|
|
235
|
+
| Lock contention | Main waits on a lock a background job holds | Use an actor or shrink the critical section |
|
|
236
|
+
| Layout thrash | `layoutSubviews` runs over and over | Batch layout changes, avoid forcing layout |
|
|
237
|
+
| Large JSON decode on main | Screen stalls during load | Decode off the main thread |
|
|
238
|
+
| Synchronous image decoding | Jank while scrolling an image list | `AsyncImage`, or decode and downsample off main |
|
|
242
239
|
|
|
243
|
-
## Build
|
|
240
|
+
## Build Failures
|
|
244
241
|
|
|
245
|
-
###
|
|
242
|
+
### Compiler diagnostics
|
|
246
243
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
244
|
+
Fix the first error first; many later errors cascade from it. Search the log
|
|
245
|
+
for the message text (for example `error: cannot convert`). The Report
|
|
246
|
+
Navigator (Cmd+9) keeps the full, timestamped build log.
|
|
250
247
|
|
|
251
|
-
###
|
|
248
|
+
### SwiftPM resolution
|
|
252
249
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
250
|
+
When versions clash, resolution fails and the message names the requirement
|
|
251
|
+
that cannot be met, typically a range such as `1.0.0..<2.0.0` on one package.
|
|
252
|
+
Read `Package.resolved`, then loosen or align the version requirements. When
|
|
253
|
+
the cache itself is suspect:
|
|
256
254
|
|
|
257
|
-
|
|
258
|
-
# Reset package caches if needed:
|
|
259
|
-
rm -rf ~/Library/Caches/org.swift.swiftpm
|
|
255
|
+
```bash
|
|
260
256
|
rm -rf .build
|
|
257
|
+
rm -rf "$HOME/Library/Caches/org.swift.swiftpm"
|
|
261
258
|
swift package resolve
|
|
262
259
|
```
|
|
263
260
|
|
|
264
|
-
###
|
|
261
|
+
### Missing modules and linker errors
|
|
265
262
|
|
|
266
|
-
|
|
|
267
|
-
|
|
268
|
-
| `No such module 'Foo'` |
|
|
269
|
-
| `Undefined symbol` |
|
|
270
|
-
| `duplicate symbol` | Two targets
|
|
263
|
+
| Message | Look at |
|
|
264
|
+
|---------|---------|
|
|
265
|
+
| `No such module 'Foo'` | Is the file in the right target? Then the import and framework search paths |
|
|
266
|
+
| `Undefined symbol` | A framework missing from the link phase, or the wrong architecture |
|
|
267
|
+
| `duplicate symbol` | Two targets defining one symbol; Objective-C name clashes |
|
|
271
268
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
- `OTHER_LDFLAGS`
|
|
275
|
-
- `SWIFT_INCLUDE_PATHS`
|
|
276
|
-
- `BUILD_LIBRARY_FOR_DISTRIBUTION` (for XCFrameworks)
|
|
269
|
+
Check these build settings first: `FRAMEWORK_SEARCH_PATHS`, `OTHER_LDFLAGS`,
|
|
270
|
+
`SWIFT_INCLUDE_PATHS`, and `BUILD_LIBRARY_FOR_DISTRIBUTION` for XCFrameworks.
|
|
277
271
|
|
|
278
|
-
## Instruments
|
|
272
|
+
## Instruments
|
|
279
273
|
|
|
280
|
-
###
|
|
274
|
+
### Picking a template
|
|
281
275
|
|
|
282
|
-
|
|
|
276
|
+
| Question | Template |
|
|
283
277
|
|----------|----------|
|
|
284
|
-
|
|
|
285
|
-
|
|
|
286
|
-
|
|
|
287
|
-
|
|
|
288
|
-
|
|
|
289
|
-
|
|
|
290
|
-
|
|
|
291
|
-
|
|
|
292
|
-
|
|
|
293
|
-
|
|
294
|
-
### xctrace
|
|
278
|
+
| High CPU, slow UI, where is the time going? | Time Profiler |
|
|
279
|
+
| Memory growth, object lifetimes | Allocations |
|
|
280
|
+
| Suspected retain cycles or abandoned objects | Leaks |
|
|
281
|
+
| Request timing and payloads | Network |
|
|
282
|
+
| How often SwiftUI bodies run and why | SwiftUI |
|
|
283
|
+
| Dropped frames, blending, commit and render cost | Animation Hitches, Core Animation instruments |
|
|
284
|
+
| Battery drain, heat, background energy | Power Profiler |
|
|
285
|
+
| Heavy or slow disk access | File Activity |
|
|
286
|
+
| Scheduling, system calls, VM faults | System Trace |
|
|
287
|
+
|
|
288
|
+
### xctrace on the command line and in CI
|
|
295
289
|
|
|
296
290
|
```bash
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
--output profile.trace \
|
|
302
|
-
--launch -- /path/to/MyApp.app
|
|
303
|
-
|
|
304
|
-
# Export trace data as XML for automated analysis
|
|
305
|
-
xcrun xctrace export --input profile.trace --xpath '/trace-toc/run/data/table'
|
|
306
|
-
|
|
307
|
-
# List available templates
|
|
291
|
+
xcrun xctrace record --device "QA iPhone" \
|
|
292
|
+
--template "Time Profiler" --instrument "Allocations" \
|
|
293
|
+
--output launch.trace --launch -- /path/to/Atlas.app
|
|
294
|
+
xcrun xctrace export --input launch.trace --xpath '/trace-toc/run/data/table'
|
|
308
295
|
xcrun xctrace list templates
|
|
309
|
-
|
|
310
|
-
# List connected devices
|
|
311
296
|
xcrun xctrace list devices
|
|
312
297
|
```
|
|
313
298
|
|
|
314
|
-
|
|
315
|
-
`--instrument`.
|
|
316
|
-
|
|
299
|
+
A recording takes exactly one `--template`; add further instruments with
|
|
300
|
+
`--instrument`. Everything after `--launch --` is the app and its arguments.
|
|
301
|
+
Run the same recording in CI and compare the exported tables between builds to
|
|
302
|
+
catch regressions.
|
|
317
303
|
|
|
318
304
|
## Common Mistakes
|
|
319
305
|
|
|
320
|
-
###
|
|
306
|
+
### `print()` instead of `Logger`
|
|
321
307
|
|
|
322
|
-
`print()`
|
|
323
|
-
|
|
308
|
+
Output from `print()` carries no subsystem, category or privacy annotation, so
|
|
309
|
+
nobody can filter it later. Use unified logging:
|
|
324
310
|
|
|
325
311
|
```swift
|
|
326
|
-
// WRONG - unstructured and not filterable by subsystem/category
|
|
327
|
-
print("user tapped button, state: \(viewModel.state)")
|
|
328
|
-
print("network response: \(data)")
|
|
329
|
-
|
|
330
|
-
// CORRECT - structured logging with Logger
|
|
331
312
|
import os
|
|
332
313
|
|
|
333
|
-
let
|
|
334
|
-
|
|
335
|
-
logger.debug("Button tapped, state: \(viewModel.state, privacy: .public)")
|
|
336
|
-
logger.info("Network response received, bytes: \(data.count)")
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
`Logger` messages appear in Console.app with filtering by subsystem and
|
|
340
|
-
category, and `.debug` messages are written to the in-memory log store only (not persisted to disk in release builds).
|
|
341
|
-
|
|
342
|
-
### DON'T: Forget to enable Malloc Stack Logging before memory debugging
|
|
314
|
+
let log = Logger(subsystem: "app.atlas.checkout", category: "Orders")
|
|
343
315
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
```swift
|
|
349
|
-
// WRONG - open Memory Graph without enabling Malloc Stack Logging
|
|
350
|
-
// Result: leaked objects visible but no allocation backtrace
|
|
351
|
-
|
|
352
|
-
// CORRECT - enable BEFORE running:
|
|
353
|
-
// Scheme > Run > Diagnostics > check "Malloc Stack Logging: All Allocations"
|
|
354
|
-
// Then run, reproduce the leak, and open Memory Graph
|
|
316
|
+
func submit(order id: String, items: Int) {
|
|
317
|
+
log.debug("Submitting \(id, privacy: .public) with \(items) items")
|
|
318
|
+
log.info("Order submitted")
|
|
319
|
+
}
|
|
355
320
|
```
|
|
356
321
|
|
|
357
|
-
|
|
322
|
+
Console.app filters by subsystem and category. By default `.debug` messages
|
|
323
|
+
stay in the in-memory log store and are not persisted to disk.
|
|
358
324
|
|
|
359
|
-
|
|
360
|
-
variables, and reorder code. LLDB cannot display optimized-away values.
|
|
325
|
+
### Memory Graph without Malloc Stack Logging
|
|
361
326
|
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
// Release builds: variables show as "<optimized out>" in debugger
|
|
327
|
+
The graph still shows leaked objects but not where they were allocated. Before
|
|
328
|
+
launching, choose All Allocations for Malloc Stack Logging in the scheme's
|
|
329
|
+
Diagnostics tab; then run, reproduce and open the graph.
|
|
366
330
|
|
|
367
|
-
|
|
368
|
-
// Debugging: use Debug configuration (full symbols, no optimization)
|
|
369
|
-
// Profiling: use Release configuration (realistic performance)
|
|
370
|
-
```
|
|
331
|
+
### Debugging or profiling the wrong configuration
|
|
371
332
|
|
|
372
|
-
|
|
333
|
+
Optimised Release code inlines, reorders and drops variables, so LLDB prints
|
|
334
|
+
`<optimized out>`. Debug builds add runtime checks that skew timings. Debug
|
|
335
|
+
with the Debug configuration; profile with Release.
|
|
373
336
|
|
|
374
|
-
|
|
375
|
-
specific case you care about.
|
|
337
|
+
### Stopping on every loop iteration
|
|
376
338
|
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
process(item) // breakpoint here stops on EVERY item
|
|
381
|
-
}
|
|
339
|
+
Add a condition instead:
|
|
340
|
+
`br set -f OrderList.swift -l 42 -c "row.id == wantedID"`, or right-click the
|
|
341
|
+
breakpoint in Xcode, choose Edit Breakpoint and fill in Condition.
|
|
382
342
|
|
|
383
|
-
|
|
384
|
-
// (lldb) br set -f MyFile.swift -l 42 -c "item.id == targetID"
|
|
385
|
-
// Or in Xcode: right-click breakpoint > Edit > add Condition
|
|
386
|
-
```
|
|
343
|
+
### Dismissing Thread Sanitizer warnings
|
|
387
344
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
intermittently. Treat them as real bugs unless you have isolated a tool issue.
|
|
345
|
+
A TSan report is a real data race that may crash only now and then. Treat it as
|
|
346
|
+
a bug until you can show the tool itself is wrong. Protect the shared state,
|
|
347
|
+
for example with an actor:
|
|
392
348
|
|
|
393
349
|
```swift
|
|
394
|
-
|
|
395
|
-
var
|
|
350
|
+
actor ThumbnailCache {
|
|
351
|
+
private var images: [URL: Data] = [:]
|
|
396
352
|
|
|
397
|
-
|
|
398
|
-
actor CacheActor {
|
|
399
|
-
var cache: [String: Data] = [:]
|
|
353
|
+
func image(for url: URL) -> Data? { images[url] }
|
|
400
354
|
|
|
401
|
-
func
|
|
402
|
-
func set(_ key: String, _ value: Data) { cache[key] = value }
|
|
355
|
+
func store(_ data: Data, for url: URL) { images[url] = data }
|
|
403
356
|
}
|
|
404
357
|
```
|
|
405
358
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
### Correction Pattern: Flawed Memory and Hang Plans
|
|
359
|
+
Turn it on in the scheme's Diagnostics tab. Apps for iOS, iPadOS, tvOS,
|
|
360
|
+
visionOS and watchOS get it in Simulator; the only devices Apple lists as
|
|
361
|
+
supported are Macs running 64-bit macOS apps.
|
|
411
362
|
|
|
412
|
-
|
|
363
|
+
### Correcting a flawed memory or hang plan
|
|
413
364
|
|
|
414
|
-
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
commonly report main-run-loop busy periods over 250 ms, while a few hundred
|
|
422
|
-
milliseconds can still feel unresponsive to users.
|
|
365
|
+
- Leaks catches abandoned, unreachable allocations and isolated unreachable
|
|
366
|
+
cycles. It does not prove that every cycle still reachable from a root is
|
|
367
|
+
gone; use the Memory Graph and Allocations generations for those.
|
|
368
|
+
- For growth: generations around the repro, the Memory Graph to see who holds
|
|
369
|
+
the memory, and stack logging to see where it came from.
|
|
370
|
+
- For severity: tools report above 250 ms, but users can feel a few hundred
|
|
371
|
+
milliseconds. Do not treat "under the tool threshold" as "fine".
|
|
423
372
|
|
|
424
373
|
## Review Checklist
|
|
425
374
|
|
|
426
|
-
- [ ]
|
|
427
|
-
- [ ] Malloc Stack Logging
|
|
428
|
-
- [ ] Memory Graph
|
|
429
|
-
- [ ] Delegates declared
|
|
430
|
-
- [ ]
|
|
431
|
-
- [ ] Timers use
|
|
432
|
-
- [ ] Thread Sanitizer
|
|
433
|
-
- [ ]
|
|
434
|
-
- [ ] Time Profiler
|
|
435
|
-
- [ ]
|
|
436
|
-
- [ ] `OSSignposter`
|
|
437
|
-
- [ ] Conditional breakpoints
|
|
438
|
-
|
|
439
|
-
##
|
|
440
|
-
|
|
441
|
-
- [Logging
|
|
442
|
-
- [Logger](https://
|
|
443
|
-
- [OSSignposter](https://
|
|
444
|
-
- [
|
|
445
|
-
- [Recording performance data
|
|
446
|
-
- [
|
|
447
|
-
- [Data races](https://
|
|
448
|
-
- [
|
|
449
|
-
- [
|
|
450
|
-
- [
|
|
451
|
-
- [
|
|
452
|
-
- [
|
|
453
|
-
- LLDB command reference: [references/lldb-patterns.md](references/lldb-patterns.md)
|
|
454
|
-
- Instruments template guide: [references/instruments-guide.md](references/instruments-guide.md)
|
|
375
|
+
- [ ] `os.Logger` instead of `print()`
|
|
376
|
+
- [ ] Malloc Stack Logging on before memory sessions
|
|
377
|
+
- [ ] Memory Graph checked after dismiss and deallocation flows
|
|
378
|
+
- [ ] Delegates declared `weak var`
|
|
379
|
+
- [ ] Stored closures capture `[weak self]`
|
|
380
|
+
- [ ] Timers use the block API with `[weak self]`
|
|
381
|
+
- [ ] Thread Sanitizer on in Simulator test schemes when chasing races
|
|
382
|
+
- [ ] Main thread free of blocking I/O and long computations
|
|
383
|
+
- [ ] Time Profiler baselines recorded from Release builds
|
|
384
|
+
- [ ] Failed builds read from the earliest error down
|
|
385
|
+
- [ ] `OSSignposter` intervals around custom performance-critical work
|
|
386
|
+
- [ ] Conditional breakpoints for loops and collections
|
|
387
|
+
|
|
388
|
+
## Apple Documentation
|
|
389
|
+
|
|
390
|
+
- [Logging](https://developer.apple.com/documentation/os/logging)
|
|
391
|
+
- [Logger](https://developer.apple.com/documentation/os/logger)
|
|
392
|
+
- [OSSignposter](https://developer.apple.com/documentation/os/ossignposter)
|
|
393
|
+
- [Writing log messages](https://developer.apple.com/documentation/os/generating-log-messages-from-your-code)
|
|
394
|
+
- [Recording performance data](https://developer.apple.com/documentation/os/recording-performance-data)
|
|
395
|
+
- [Catching memory, threading and crash bugs early](https://developer.apple.com/documentation/xcode/diagnosing-memory-thread-and-crash-issues-early)
|
|
396
|
+
- [Data races](https://developer.apple.com/documentation/xcode/data-races)
|
|
397
|
+
- [Lowering memory use](https://developer.apple.com/documentation/xcode/reducing-your-app-s-memory-use)
|
|
398
|
+
- [Improving app responsiveness](https://developer.apple.com/documentation/xcode/improving-app-responsiveness)
|
|
399
|
+
- [Battery use](https://developer.apple.com/documentation/xcode/analyzing-your-app-s-battery-use)
|
|
400
|
+
- [Performance of a shipped app](https://developer.apple.com/documentation/xcode/analyzing-the-performance-of-your-shipping-app)
|
|
401
|
+
- [Instruments tutorials](https://developer.apple.com/tutorials/instruments)
|