@mmerterden/multi-agent-pipeline 20.7.0 → 20.8.1

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.
Files changed (284) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/LICENSE +0 -10
  3. package/docs/facts.json +1 -1
  4. package/manifest.json +285 -285
  5. package/package.json +3 -3
  6. package/pipeline/lib/redact.mjs +3 -2
  7. package/pipeline/scripts/_notices.mjs +1 -1
  8. package/pipeline/scripts/gen-skills-index.mjs +13 -1
  9. package/pipeline/scripts/pre-commit-check.sh +4 -0
  10. package/pipeline/skills/.skill-manifest.json +69 -69
  11. package/pipeline/skills/shared/README.md +70 -70
  12. package/pipeline/skills/shared/external/alarmkit/SKILL.md +373 -381
  13. package/pipeline/skills/shared/external/alarmkit/evals/evals.json +23 -18
  14. package/pipeline/skills/shared/external/alarmkit/references/alarmkit-patterns.md +328 -378
  15. package/pipeline/skills/shared/external/app-clips/SKILL.md +260 -160
  16. package/pipeline/skills/shared/external/app-clips/evals/evals.json +27 -27
  17. package/pipeline/skills/shared/external/app-clips/references/data-handoff-notifications-location.md +150 -83
  18. package/pipeline/skills/shared/external/app-clips/references/routing-and-experiences.md +135 -83
  19. package/pipeline/skills/shared/external/app-clips/references/size-capabilities-and-promotion.md +143 -85
  20. package/pipeline/skills/shared/external/app-intents/SKILL.md +302 -304
  21. package/pipeline/skills/shared/external/app-intents/evals/evals.json +21 -21
  22. package/pipeline/skills/shared/external/app-intents/references/appintents-advanced.md +594 -894
  23. package/pipeline/skills/shared/external/app-store-optimization/SKILL.md +345 -277
  24. package/pipeline/skills/shared/external/app-store-optimization/evals/evals.json +27 -23
  25. package/pipeline/skills/shared/external/app-store-optimization/references/keyword-research-methodology.md +107 -121
  26. package/pipeline/skills/shared/external/app-store-optimization/references/product-page-variants.md +145 -165
  27. package/pipeline/skills/shared/external/app-store-review/SKILL.md +306 -326
  28. package/pipeline/skills/shared/external/app-store-review/evals/evals.json +21 -21
  29. package/pipeline/skills/shared/external/app-store-review/references/privacy-manifest.md +105 -67
  30. package/pipeline/skills/shared/external/app-store-review/references/review-checklists.md +114 -101
  31. package/pipeline/skills/shared/external/apple-on-device-ai/SKILL.md +335 -360
  32. package/pipeline/skills/shared/external/apple-on-device-ai/evals/evals.json +24 -27
  33. package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-conversion.md +215 -322
  34. package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-optimization.md +161 -256
  35. package/pipeline/skills/shared/external/apple-on-device-ai/references/foundation-models.md +277 -387
  36. package/pipeline/skills/shared/external/apple-on-device-ai/references/mlx-swift.md +196 -210
  37. package/pipeline/skills/shared/external/authentication/SKILL.md +277 -381
  38. package/pipeline/skills/shared/external/authentication/evals/evals.json +25 -25
  39. package/pipeline/skills/shared/external/authentication/references/keychain-biometric.md +135 -178
  40. package/pipeline/skills/shared/external/authentication/references/passkeys.md +111 -147
  41. package/pipeline/skills/shared/external/avkit/SKILL.md +267 -364
  42. package/pipeline/skills/shared/external/avkit/evals/evals.json +26 -26
  43. package/pipeline/skills/shared/external/avkit/references/avkit-patterns.md +375 -493
  44. package/pipeline/skills/shared/external/background-processing/SKILL.md +274 -384
  45. package/pipeline/skills/shared/external/background-processing/evals/evals.json +22 -22
  46. package/pipeline/skills/shared/external/background-processing/references/background-task-patterns.md +173 -321
  47. package/pipeline/skills/shared/external/callkit-voip/SKILL.md +290 -371
  48. package/pipeline/skills/shared/external/callkit-voip/evals/evals.json +24 -24
  49. package/pipeline/skills/shared/external/callkit-voip/references/callkit-patterns.md +175 -343
  50. package/pipeline/skills/shared/external/cloudkit-sync/SKILL.md +292 -381
  51. package/pipeline/skills/shared/external/cloudkit-sync/evals/evals.json +33 -30
  52. package/pipeline/skills/shared/external/cloudkit-sync/references/cloudkit-patterns.md +227 -355
  53. package/pipeline/skills/shared/external/contacts-framework/SKILL.md +197 -346
  54. package/pipeline/skills/shared/external/contacts-framework/evals/evals.json +19 -21
  55. package/pipeline/skills/shared/external/contacts-framework/references/contacts-patterns.md +169 -308
  56. package/pipeline/skills/shared/external/core-bluetooth/SKILL.md +228 -376
  57. package/pipeline/skills/shared/external/core-bluetooth/evals/evals.json +25 -22
  58. package/pipeline/skills/shared/external/core-bluetooth/references/ble-patterns.md +257 -337
  59. package/pipeline/skills/shared/external/core-data/SKILL.md +302 -368
  60. package/pipeline/skills/shared/external/core-data/evals/evals.json +30 -27
  61. package/pipeline/skills/shared/external/core-motion/SKILL.md +235 -324
  62. package/pipeline/skills/shared/external/core-motion/evals/evals.json +31 -27
  63. package/pipeline/skills/shared/external/core-motion/references/motion-patterns.md +210 -310
  64. package/pipeline/skills/shared/external/core-nfc/SKILL.md +292 -366
  65. package/pipeline/skills/shared/external/core-nfc/evals/evals.json +22 -24
  66. package/pipeline/skills/shared/external/core-nfc/references/nfc-patterns.md +233 -329
  67. package/pipeline/skills/shared/external/coreml/SKILL.md +323 -367
  68. package/pipeline/skills/shared/external/coreml/evals/evals.json +24 -21
  69. package/pipeline/skills/shared/external/coreml/references/coreml-swift-integration.md +562 -565
  70. package/pipeline/skills/shared/external/cryptokit/SKILL.md +253 -394
  71. package/pipeline/skills/shared/external/cryptokit/evals/evals.json +20 -18
  72. package/pipeline/skills/shared/external/cryptokit/references/cryptokit-patterns.md +299 -488
  73. package/pipeline/skills/shared/external/debugging-instruments/SKILL.md +270 -323
  74. package/pipeline/skills/shared/external/debugging-instruments/evals/evals.json +27 -30
  75. package/pipeline/skills/shared/external/debugging-instruments/references/instruments-guide.md +167 -315
  76. package/pipeline/skills/shared/external/debugging-instruments/references/lldb-patterns.md +140 -193
  77. package/pipeline/skills/shared/external/device-integrity/SKILL.md +236 -353
  78. package/pipeline/skills/shared/external/device-integrity/evals/evals.json +25 -21
  79. package/pipeline/skills/shared/external/device-integrity/references/device-integrity-patterns.md +159 -197
  80. package/pipeline/skills/shared/external/energykit/SKILL.md +225 -392
  81. package/pipeline/skills/shared/external/energykit/evals/evals.json +29 -28
  82. package/pipeline/skills/shared/external/energykit/references/energykit-patterns.md +174 -470
  83. package/pipeline/skills/shared/external/eventkit-calendar/SKILL.md +261 -383
  84. package/pipeline/skills/shared/external/eventkit-calendar/evals/evals.json +25 -22
  85. package/pipeline/skills/shared/external/eventkit-calendar/references/eventkit-patterns.md +165 -268
  86. package/pipeline/skills/shared/external/healthkit/SKILL.md +252 -303
  87. package/pipeline/skills/shared/external/healthkit/evals/evals.json +24 -23
  88. package/pipeline/skills/shared/external/healthkit/references/healthkit-patterns.md +369 -523
  89. package/pipeline/skills/shared/external/homekit-matter/SKILL.md +233 -348
  90. package/pipeline/skills/shared/external/homekit-matter/evals/evals.json +27 -22
  91. package/pipeline/skills/shared/external/homekit-matter/references/matter-commissioning.md +199 -305
  92. package/pipeline/skills/shared/external/ios-accessibility/SKILL.md +368 -340
  93. package/pipeline/skills/shared/external/ios-accessibility/evals/evals.json +28 -27
  94. package/pipeline/skills/shared/external/ios-accessibility/references/a11y-patterns.md +314 -260
  95. package/pipeline/skills/shared/external/ios-accessibility/references/media-accessibility.md +97 -67
  96. package/pipeline/skills/shared/external/ios-accessibility/references/nutrition-labels.md +165 -101
  97. package/pipeline/skills/shared/external/ios-localization/SKILL.md +258 -371
  98. package/pipeline/skills/shared/external/ios-localization/evals/evals.json +23 -23
  99. package/pipeline/skills/shared/external/ios-localization/references/formatstyle-locale.md +283 -491
  100. package/pipeline/skills/shared/external/ios-localization/references/string-catalogs.md +313 -440
  101. package/pipeline/skills/shared/external/ios-networking/SKILL.md +265 -341
  102. package/pipeline/skills/shared/external/ios-networking/evals/evals.json +24 -24
  103. package/pipeline/skills/shared/external/ios-networking/references/background-websocket.md +425 -652
  104. package/pipeline/skills/shared/external/ios-networking/references/file-storage-patterns.md +143 -285
  105. package/pipeline/skills/shared/external/ios-networking/references/lightweight-clients.md +93 -53
  106. package/pipeline/skills/shared/external/ios-networking/references/network-framework.md +231 -456
  107. package/pipeline/skills/shared/external/ios-networking/references/urlsession-patterns.md +517 -784
  108. package/pipeline/skills/shared/external/ios-simulator/SKILL.md +265 -393
  109. package/pipeline/skills/shared/external/ios-simulator/evals/evals.json +21 -21
  110. package/pipeline/skills/shared/external/ios-simulator/references/simctl-commands.md +177 -270
  111. package/pipeline/skills/shared/external/live-activities/SKILL.md +318 -360
  112. package/pipeline/skills/shared/external/live-activities/evals/evals.json +21 -21
  113. package/pipeline/skills/shared/external/live-activities/references/activitykit-patterns.md +478 -710
  114. package/pipeline/skills/shared/external/localization-reuse-map/SKILL.md +3 -3
  115. package/pipeline/skills/shared/external/localization-reuse-map/example-mapping.json +1 -1
  116. package/pipeline/skills/shared/external/localization-reuse-map/reference/format-and-output.md +8 -7
  117. package/pipeline/skills/shared/external/localization-reuse-map/reference/publish-and-snapshot.md +2 -2
  118. package/pipeline/skills/shared/external/localization-reuse-map/reference/sources-and-recipes.md +5 -2
  119. package/pipeline/skills/shared/external/localization-reuse-map/scripts/_shared.py +100 -0
  120. package/pipeline/skills/shared/external/localization-reuse-map/scripts/build-artifact.py +45 -26
  121. package/pipeline/skills/shared/external/localization-reuse-map/scripts/build-spreadsheet.py +14 -16
  122. package/pipeline/skills/shared/external/localization-reuse-map/scripts/fetch-annotations.py +12 -5
  123. package/pipeline/skills/shared/external/localization-reuse-map/scripts/fetch-legacy-labels.py +2 -1
  124. package/pipeline/skills/shared/external/localization-reuse-map/scripts/publish-confluence.py +6 -5
  125. package/pipeline/skills/shared/external/localization-reuse-map/scripts/render-overlay.py +44 -18
  126. package/pipeline/skills/shared/external/localization-reuse-map/scripts/resolve-legacy-values.py +5 -2
  127. package/pipeline/skills/shared/external/localization-reuse-map/scripts/resolve-new-values.py +10 -11
  128. package/pipeline/skills/shared/external/localization-reuse-map/scripts/scan-screen-keys.py +4 -33
  129. package/pipeline/skills/shared/external/localization-reuse-map/scripts/verify-map.py +12 -59
  130. package/pipeline/skills/shared/external/mapkit-location/SKILL.md +297 -267
  131. package/pipeline/skills/shared/external/mapkit-location/evals/evals.json +28 -24
  132. package/pipeline/skills/shared/external/mapkit-location/references/mapkit-corelocation-patterns.md +378 -532
  133. package/pipeline/skills/shared/external/mapkit-location/references/mapkit-patterns.md +397 -499
  134. package/pipeline/skills/shared/external/metrickit-diagnostics/SKILL.md +165 -348
  135. package/pipeline/skills/shared/external/metrickit-diagnostics/evals/evals.json +26 -23
  136. package/pipeline/skills/shared/external/metrickit-diagnostics/references/metrickit-patterns.md +123 -130
  137. package/pipeline/skills/shared/external/musickit-audio/SKILL.md +189 -315
  138. package/pipeline/skills/shared/external/musickit-audio/evals/evals.json +22 -21
  139. package/pipeline/skills/shared/external/musickit-audio/references/musickit-patterns.md +181 -270
  140. package/pipeline/skills/shared/external/natural-language/SKILL.md +188 -340
  141. package/pipeline/skills/shared/external/natural-language/evals/evals.json +21 -21
  142. package/pipeline/skills/shared/external/natural-language/references/translation-patterns.md +171 -225
  143. package/pipeline/skills/shared/external/passkit-wallet/SKILL.md +258 -392
  144. package/pipeline/skills/shared/external/passkit-wallet/evals/evals.json +30 -29
  145. package/pipeline/skills/shared/external/passkit-wallet/references/wallet-passes.md +164 -231
  146. package/pipeline/skills/shared/external/pdfkit/SKILL.md +312 -344
  147. package/pipeline/skills/shared/external/pdfkit/evals/evals.json +19 -19
  148. package/pipeline/skills/shared/external/pdfkit/references/pdfkit-patterns.md +413 -624
  149. package/pipeline/skills/shared/external/pencilkit-drawing/SKILL.md +242 -358
  150. package/pipeline/skills/shared/external/pencilkit-drawing/evals/evals.json +25 -21
  151. package/pipeline/skills/shared/external/pencilkit-drawing/references/pencilkit-patterns.md +161 -226
  152. package/pipeline/skills/shared/external/permissionkit/SKILL.md +282 -400
  153. package/pipeline/skills/shared/external/permissionkit/evals/evals.json +27 -30
  154. package/pipeline/skills/shared/external/permissionkit/references/permissionkit-patterns.md +237 -350
  155. package/pipeline/skills/shared/external/photos-camera-media/SKILL.md +276 -325
  156. package/pipeline/skills/shared/external/photos-camera-media/references/av-playback.md +299 -545
  157. package/pipeline/skills/shared/external/photos-camera-media/references/camera-capture.md +344 -588
  158. package/pipeline/skills/shared/external/photos-camera-media/references/image-loading-caching.md +316 -660
  159. package/pipeline/skills/shared/external/photos-camera-media/references/photokit-patterns.md +270 -416
  160. package/pipeline/skills/shared/external/push-notifications/SKILL.md +312 -340
  161. package/pipeline/skills/shared/external/push-notifications/evals/evals.json +27 -26
  162. package/pipeline/skills/shared/external/push-notifications/references/notification-patterns.md +328 -485
  163. package/pipeline/skills/shared/external/push-notifications/references/rich-notifications.md +327 -560
  164. package/pipeline/skills/shared/external/realitykit-ar/SKILL.md +218 -410
  165. package/pipeline/skills/shared/external/realitykit-ar/evals/evals.json +24 -27
  166. package/pipeline/skills/shared/external/realitykit-ar/references/realitykit-patterns.md +221 -348
  167. package/pipeline/skills/shared/external/shareplay-activities/SKILL.md +222 -393
  168. package/pipeline/skills/shared/external/shareplay-activities/evals/evals.json +23 -24
  169. package/pipeline/skills/shared/external/shareplay-activities/references/shareplay-patterns.md +280 -420
  170. package/pipeline/skills/shared/external/skill-creator/template.md +7 -1
  171. package/pipeline/skills/shared/external/speech-recognition/SKILL.md +217 -421
  172. package/pipeline/skills/shared/external/speech-recognition/evals/evals.json +23 -26
  173. package/pipeline/skills/shared/external/speech-recognition/references/speechanalyzer-patterns.md +133 -125
  174. package/pipeline/skills/shared/external/storekit/SKILL.md +228 -204
  175. package/pipeline/skills/shared/external/storekit/evals/evals.json +27 -24
  176. package/pipeline/skills/shared/external/storekit/references/app-review-guidelines.md +98 -109
  177. package/pipeline/skills/shared/external/storekit/references/core-patterns.md +302 -241
  178. package/pipeline/skills/shared/external/storekit/references/storekit-advanced.md +356 -649
  179. package/pipeline/skills/shared/external/swift-api-design-guidelines/SKILL.md +274 -399
  180. package/pipeline/skills/shared/external/swift-api-design-guidelines/evals/evals.json +22 -24
  181. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/argument-labels-and-parameters.md +107 -108
  182. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/conventions-and-special-rules.md +93 -165
  183. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/naming-and-clarity.md +99 -137
  184. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/side-effects-and-mutating-pairs.md +77 -120
  185. package/pipeline/skills/shared/external/swift-architecture/SKILL.md +334 -350
  186. package/pipeline/skills/shared/external/swift-architecture/evals/evals.json +22 -22
  187. package/pipeline/skills/shared/external/swift-charts/SKILL.md +208 -394
  188. package/pipeline/skills/shared/external/swift-charts/evals/evals.json +27 -30
  189. package/pipeline/skills/shared/external/swift-charts/references/charts-patterns.md +351 -762
  190. package/pipeline/skills/shared/external/swift-codable/SKILL.md +339 -343
  191. package/pipeline/skills/shared/external/swift-codable/evals/evals.json +20 -20
  192. package/pipeline/skills/shared/external/swift-concurrency/SKILL.md +304 -351
  193. package/pipeline/skills/shared/external/swift-concurrency/evals/evals.json +27 -24
  194. package/pipeline/skills/shared/external/swift-concurrency/references/approachable-concurrency.md +65 -80
  195. package/pipeline/skills/shared/external/swift-concurrency/references/async-algorithms.md +48 -84
  196. package/pipeline/skills/shared/external/swift-concurrency/references/bridging-interop.md +134 -79
  197. package/pipeline/skills/shared/external/swift-concurrency/references/concurrency-patterns.md +145 -167
  198. package/pipeline/skills/shared/external/swift-concurrency/references/diagnostics.md +62 -50
  199. package/pipeline/skills/shared/external/swift-concurrency/references/swiftui-concurrency.md +92 -121
  200. package/pipeline/skills/shared/external/swift-concurrency/references/synchronization-primitives.md +177 -241
  201. package/pipeline/skills/shared/external/swift-formatstyle/SKILL.md +258 -234
  202. package/pipeline/skills/shared/external/swift-language/SKILL.md +342 -382
  203. package/pipeline/skills/shared/external/swift-language/evals/evals.json +24 -27
  204. package/pipeline/skills/shared/external/swift-language/references/swift-attributes-interop.md +79 -56
  205. package/pipeline/skills/shared/external/swift-language/references/swift-patterns-extended.md +297 -340
  206. package/pipeline/skills/shared/external/swift-security/SKILL.md +183 -162
  207. package/pipeline/skills/shared/external/swift-security/evals/evals.json +25 -25
  208. package/pipeline/skills/shared/external/swift-security/references/biometric-authentication.md +314 -469
  209. package/pipeline/skills/shared/external/swift-security/references/certificate-trust.md +411 -476
  210. package/pipeline/skills/shared/external/swift-security/references/common-anti-patterns.md +260 -530
  211. package/pipeline/skills/shared/external/swift-security/references/compliance-owasp-mapping.md +270 -477
  212. package/pipeline/skills/shared/external/swift-security/references/credential-storage-patterns.md +573 -571
  213. package/pipeline/skills/shared/external/swift-security/references/cryptokit-public-key.md +370 -441
  214. package/pipeline/skills/shared/external/swift-security/references/cryptokit-symmetric.md +332 -433
  215. package/pipeline/skills/shared/external/swift-security/references/keychain-access-control.md +346 -468
  216. package/pipeline/skills/shared/external/swift-security/references/keychain-fundamentals.md +375 -491
  217. package/pipeline/skills/shared/external/swift-security/references/keychain-item-classes.md +431 -432
  218. package/pipeline/skills/shared/external/swift-security/references/keychain-sharing.md +328 -425
  219. package/pipeline/skills/shared/external/swift-security/references/migration-legacy-stores.md +341 -579
  220. package/pipeline/skills/shared/external/swift-security/references/secure-enclave.md +397 -457
  221. package/pipeline/skills/shared/external/swift-security/references/testing-security-code.md +354 -614
  222. package/pipeline/skills/shared/external/swift-testing/SKILL.md +191 -175
  223. package/pipeline/skills/shared/external/swift-testing/evals/evals.json +26 -24
  224. package/pipeline/skills/shared/external/swift-testing/references/testing-advanced.md +81 -84
  225. package/pipeline/skills/shared/external/swift-testing/references/testing-patterns.md +317 -433
  226. package/pipeline/skills/shared/external/swiftdata/SKILL.md +394 -256
  227. package/pipeline/skills/shared/external/swiftdata/evals/evals.json +24 -24
  228. package/pipeline/skills/shared/external/swiftdata/references/core-data-coexistence.md +206 -402
  229. package/pipeline/skills/shared/external/swiftdata/references/indexing.md +59 -52
  230. package/pipeline/skills/shared/external/swiftdata/references/predicate-pitfalls.md +57 -33
  231. package/pipeline/skills/shared/external/swiftdata/references/swiftdata-advanced.md +354 -747
  232. package/pipeline/skills/shared/external/swiftdata/references/swiftdata-queries.md +300 -508
  233. package/pipeline/skills/shared/external/swiftlint/SKILL.md +175 -226
  234. package/pipeline/skills/shared/external/swiftlint/references/adoption-and-configuration.md +141 -208
  235. package/pipeline/skills/shared/external/swiftlint/references/custom-rules-and-analyze.md +100 -109
  236. package/pipeline/skills/shared/external/swiftlint/references/plugins-run-scripts-and-integrations.md +159 -179
  237. package/pipeline/skills/shared/external/swiftlint/references/rule-reference.md +383 -18
  238. package/pipeline/skills/shared/external/swiftlint/references/rules-suppressions-and-baselines.md +143 -229
  239. package/pipeline/skills/shared/external/swiftui-animation/SKILL.md +283 -366
  240. package/pipeline/skills/shared/external/swiftui-animation/references/animation-advanced.md +396 -608
  241. package/pipeline/skills/shared/external/swiftui-animation/references/core-animation-bridge.md +336 -385
  242. package/pipeline/skills/shared/external/swiftui-gestures/SKILL.md +239 -349
  243. package/pipeline/skills/shared/external/swiftui-gestures/references/gesture-patterns.md +228 -310
  244. package/pipeline/skills/shared/external/swiftui-layout-components/SKILL.md +260 -249
  245. package/pipeline/skills/shared/external/swiftui-layout-components/references/form.md +92 -74
  246. package/pipeline/skills/shared/external/swiftui-layout-components/references/grids.md +112 -177
  247. package/pipeline/skills/shared/external/swiftui-layout-components/references/list.md +61 -64
  248. package/pipeline/skills/shared/external/swiftui-layout-components/references/scrollview.md +94 -134
  249. package/pipeline/skills/shared/external/swiftui-liquid-glass/SKILL.md +193 -225
  250. package/pipeline/skills/shared/external/swiftui-liquid-glass/references/liquid-glass.md +173 -327
  251. package/pipeline/skills/shared/external/swiftui-navigation/SKILL.md +201 -168
  252. package/pipeline/skills/shared/external/swiftui-navigation/references/deeplinks.md +127 -150
  253. package/pipeline/skills/shared/external/swiftui-navigation/references/navigationstack.md +134 -133
  254. package/pipeline/skills/shared/external/swiftui-navigation/references/sheets.md +152 -117
  255. package/pipeline/skills/shared/external/swiftui-navigation/references/tabview.md +111 -138
  256. package/pipeline/skills/shared/external/swiftui-patterns/SKILL.md +316 -252
  257. package/pipeline/skills/shared/external/swiftui-patterns/references/architecture-patterns.md +341 -332
  258. package/pipeline/skills/shared/external/swiftui-patterns/references/deprecated-migration.md +547 -854
  259. package/pipeline/skills/shared/external/swiftui-patterns/references/design-polish.md +485 -537
  260. package/pipeline/skills/shared/external/swiftui-patterns/references/platform-and-sharing.md +417 -499
  261. package/pipeline/skills/shared/external/swiftui-performance/SKILL.md +213 -376
  262. package/pipeline/skills/shared/external/swiftui-performance/references/demystify-swiftui-performance-wwdc23.md +86 -175
  263. package/pipeline/skills/shared/external/swiftui-performance/references/optimizing-swiftui-performance-instruments.md +89 -195
  264. package/pipeline/skills/shared/external/swiftui-performance/references/understanding-hangs-in-your-app.md +95 -182
  265. package/pipeline/skills/shared/external/swiftui-performance/references/understanding-improving-swiftui-performance.md +71 -149
  266. package/pipeline/skills/shared/external/swiftui-performance/references/wwdc-session-sources.md +21 -27
  267. package/pipeline/skills/shared/external/swiftui-uikit-interop/SKILL.md +303 -295
  268. package/pipeline/skills/shared/external/swiftui-uikit-interop/references/hosting-migration.md +204 -387
  269. package/pipeline/skills/shared/external/swiftui-uikit-interop/references/representable-recipes.md +469 -683
  270. package/pipeline/skills/shared/external/swiftui-webkit/SKILL.md +140 -186
  271. package/pipeline/skills/shared/external/swiftui-webkit/references/loading-and-observation.md +75 -86
  272. package/pipeline/skills/shared/external/swiftui-webkit/references/local-content-and-custom-schemes.md +63 -60
  273. package/pipeline/skills/shared/external/swiftui-webkit/references/migration-and-fallbacks.md +69 -137
  274. package/pipeline/skills/shared/external/swiftui-webkit/references/navigation-and-javascript.md +95 -67
  275. package/pipeline/skills/shared/external/tipkit/SKILL.md +220 -335
  276. package/pipeline/skills/shared/external/tipkit/references/tipkit-patterns.md +356 -494
  277. package/pipeline/skills/shared/external/vision-framework/SKILL.md +260 -375
  278. package/pipeline/skills/shared/external/vision-framework/references/vision-requests.md +393 -515
  279. package/pipeline/skills/shared/external/vision-framework/references/visionkit-scanner.md +363 -539
  280. package/pipeline/skills/shared/external/weatherkit/SKILL.md +160 -315
  281. package/pipeline/skills/shared/external/weatherkit/references/weatherkit-patterns.md +288 -407
  282. package/pipeline/skills/shared/external/widgetkit/SKILL.md +224 -288
  283. package/pipeline/skills/shared/external/widgetkit/references/widgetkit-advanced.md +416 -719
  284. package/pipeline/skills/shared/external/NOTICE-swift-ios-skills.md +0 -39
@@ -1,500 +1,314 @@
1
1
  ---
2
2
  name: swift-charts
3
- description: "Implement, review, or improve data visualizations using Swift Charts. Use when building bar, line, area, point, pie, donut, or iOS 26 3D charts; when adding chart selection, scrolling, annotations, axes, scales, legends, or foregroundStyle grouping; when plotting functions with BarPlot, LinePlot, AreaPlot, PointPlot, Chart3D, or SurfacePlot; or when creating heat maps, Gantt charts, grouped bars, sparklines, threshold lines, or spatial visualizations."
3
+ description: "Swift Charts: bar, line, area, point, pie, donut, iOS 26 3D charts (Chart3D, SurfacePlot), axes, scales, legends, annotations, scrolling, selection, foregroundStyle grouping, vectorized BarPlot/LinePlot/AreaPlot/PointPlot function plots, Gantt, heat maps, sparklines, grouped bars, threshold lines, spatial plots. Use when implementing, reviewing or improving a SwiftUI chart. Not for map annotations, navigation, data loading or full VoiceOver audits."
4
4
  metadata:
5
- source: "dpearson2699/swift-ios-skills (PolyForm Perimeter 1.0.0)"
5
+ source: multi-agent-pipeline
6
6
  ---
7
- # Swift Charts
8
-
9
- Build data visualizations with Swift Charts targeting iOS 26+. Compose marks
10
- inside `Chart` or `Chart3D`, configure axes and scales with view modifiers, and
11
- use vectorized plots or 3D plots when the data calls for them.
12
-
13
- See [references/charts-patterns.md](references/charts-patterns.md) for extended patterns, 3D charts, accessibility, and theming guidance.
14
-
15
- ## Contents
16
-
17
- - [Workflow](#workflow)
18
- - [Chart Container](#chart-container)
19
- - [Mark Types](#mark-types)
20
- - [Axis Customization](#axis-customization)
21
- - [Scale Configuration](#scale-configuration)
22
- - [Foreground Style and Encoding](#foreground-style-and-encoding)
23
- - [Selection (iOS 17+)](#selection-ios-17)
24
- - [Scrollable Charts (iOS 17+)](#scrollable-charts-ios-17)
25
- - [Annotations](#annotations)
26
- - [Legend](#legend)
27
- - [Vectorized Plots (iOS 18+)](#vectorized-plots-ios-18)
28
- - [3D Charts (iOS 26+)](#3d-charts-ios-26)
29
- - [Common Mistakes](#common-mistakes)
30
- - [Review Checklist](#review-checklist)
31
- - [References](#references)
32
-
33
- ## Workflow
34
7
 
35
- ### 1. Build a new chart
36
-
37
- 1. Define data as an `Identifiable` struct or use `id:` key path.
38
- 2. Choose mark type(s): `BarMark`, `LineMark`, `PointMark`, `AreaMark`,
39
- `RuleMark`, `RectangleMark`, `SectorMark`, or `SurfacePlot`.
40
- 3. Wrap 2D marks in `Chart`; use `Chart3D` only for real spatial or surface data.
41
- 4. Encode visual channels: `.foregroundStyle(by:)`, `.symbol(by:)`, `.lineStyle(by:)`.
42
- 5. Configure axes with `.chartXAxis` / `.chartYAxis`.
43
- 6. Set scale domains with `.chartXScale(domain:)` / `.chartYScale(domain:)`.
44
- 7. Add selection, scrolling, or annotations as needed.
45
- 8. For 1000+ 2D data points, use vectorized plots (`BarPlot`, `LinePlot`, etc.).
8
+ # Swift Charts
46
9
 
47
- ### 2. Review existing chart code
10
+ Baseline: iOS 26. Marks go inside `Chart` (or `Chart3D`), axes and scales are
11
+ view modifiers, and vectorized or 3D plots are used when the data calls for
12
+ them. Each API below lists its first release.
48
13
 
49
- Run through the Review Checklist at the end of this file.
14
+ Extended recipes: [chart patterns](references/charts-patterns.md).
50
15
 
51
- ## Chart Container
16
+ Outside this skill: map annotations and overlays (MapKit guidance), navigation
17
+ and deep links (`swiftui-navigation`), loading data and model ownership
18
+ (networking, concurrency and SwiftUI architecture skills), full VoiceOver
19
+ audits (`ios-accessibility`). Chart-level labels, colour, Dynamic Type and
20
+ audio graphs stay here.
52
21
 
53
- ```swift
54
- // Data-driven init (single-series)
55
- Chart(sales) { item in
56
- BarMark(x: .value("Month", item.month), y: .value("Revenue", item.revenue))
57
- }
22
+ ## Workflow
58
23
 
59
- // Content closure init (multi-series, mixed marks)
60
- Chart {
61
- ForEach(seriesA) { item in
62
- LineMark(x: .value("Date", item.date), y: .value("Value", item.value))
63
- .foregroundStyle(.blue)
64
- }
65
- RuleMark(y: .value("Target", 500))
66
- .foregroundStyle(.red)
67
- }
24
+ Building a chart:
68
25
 
69
- // Custom ID key path
70
- Chart(data, id: \.category) { item in
71
- BarMark(x: .value("Category", item.category), y: .value("Count", item.count))
72
- }
73
- ```
26
+ 1. Make each data point an `Identifiable` value, or give the chart an `id:`
27
+ key path.
28
+ 2. Choose marks: `BarMark`, `LineMark`, `PointMark`, `AreaMark`, `RuleMark`,
29
+ `RectangleMark`, `SectorMark`, or `SurfacePlot` for surfaces.
30
+ 3. Flat marks belong in `Chart`. Reserve `Chart3D` for data that truly has
31
+ three spatial dimensions or describes a surface.
32
+ 4. Encode extra dimensions with `.foregroundStyle(by:)`, `.symbol(by:)` and
33
+ `.lineStyle(by:)`.
34
+ 5. Configure axes with `.chartXAxis` and `.chartYAxis`.
35
+ 6. Fix domains with `.chartXScale(domain:)` and `.chartYScale(domain:)`.
36
+ 7. Add selection, scrolling and annotations where they help.
37
+ 8. Above roughly 1,000 points in 2D, switch to vectorized plots (`BarPlot`,
38
+ `LinePlot` and friends).
74
39
 
75
- ## Mark Types
40
+ Reviewing a chart: work down the checklist that closes this file.
76
41
 
77
- ### BarMark (iOS 16+)
42
+ ## The `Chart` Container
78
43
 
79
44
  ```swift
80
- // Vertical bar
81
- BarMark(x: .value("Month", item.month), y: .value("Sales", item.sales))
82
-
83
- // Stacked by category (automatic when same x maps to multiple bars)
84
- BarMark(x: .value("Month", item.month), y: .value("Sales", item.sales))
85
- .foregroundStyle(by: .value("Product", item.product))
86
-
87
- // Horizontal bar
88
- BarMark(x: .value("Sales", item.sales), y: .value("Month", item.month))
89
-
90
- // Interval bar (Gantt chart)
91
- BarMark(
92
- xStart: .value("Start", item.start),
93
- xEnd: .value("End", item.end),
94
- y: .value("Task", item.task)
95
- )
96
- ```
45
+ import Charts
46
+ import SwiftUI
97
47
 
98
- ### LineMark (iOS 16+)
48
+ struct StepsChart: View {
49
+ let days: [DailySteps]
99
50
 
100
- ```swift
101
- // Single line
102
- LineMark(x: .value("Date", item.date), y: .value("Price", item.price))
103
-
104
- // Multi-series via foregroundStyle encoding
105
- LineMark(x: .value("Date", item.date), y: .value("Temp", item.temp))
106
- .foregroundStyle(by: .value("City", item.city))
107
- .interpolationMethod(.catmullRom)
108
-
109
- // Multi-series with explicit series parameter
110
- LineMark(
111
- x: .value("Date", item.date),
112
- y: .value("Price", item.price),
113
- series: .value("Ticker", item.ticker)
114
- )
51
+ var body: some View {
52
+ Chart(days) { entry in
53
+ BarMark(x: .value("Date", entry.date, unit: .day),
54
+ y: .value("Steps", entry.count))
55
+ }
56
+ }
57
+ }
115
58
  ```
116
59
 
117
- ### PointMark (iOS 16+)
60
+ - `Chart(data) { item in ... }` suits a single series.
61
+ - `Chart { ForEach(...) { ... }; RuleMark(...) }` mixes marks and series.
62
+ - `Chart(data, id: \.code) { ... }` uses a custom identifier.
63
+ - Every value is wrapped as `.value("Label", value)`, a `PlottableValue`.
118
64
 
119
- ```swift
120
- PointMark(x: .value("Height", item.height), y: .value("Weight", item.weight))
121
- .foregroundStyle(by: .value("Species", item.species))
122
- .symbol(by: .value("Species", item.species))
123
- .symbolSize(100)
124
- ```
65
+ ## Marks
125
66
 
126
- ### AreaMark (iOS 16+)
67
+ All of these are iOS 16 unless noted.
127
68
 
128
69
  ```swift
129
- // Stacked area
130
- AreaMark(x: .value("Date", item.date), y: .value("Sales", item.sales))
131
- .foregroundStyle(by: .value("Category", item.category))
132
-
133
- // Range band
134
- AreaMark(
135
- x: .value("Date", item.date),
136
- yStart: .value("Min", item.min),
137
- yEnd: .value("Max", item.max)
138
- )
139
- .opacity(0.3)
70
+ Chart {
71
+ ForEach(sales) { sale in
72
+ BarMark(x: .value("Store", sale.store), y: .value("Units", sale.units))
73
+ .foregroundStyle(by: .value("Channel", sale.channel))
74
+ }
75
+ }
140
76
  ```
141
77
 
142
- ### RuleMark (iOS 16+)
78
+ - **`BarMark`**: vertical with a category on x and a value on y; swap x and y
79
+ for horizontal bars. Several bars on the same x with `.foregroundStyle(by:)`
80
+ stack automatically. `BarMark(xStart:xEnd:y:)` draws an interval, the
81
+ building block of a Gantt chart.
82
+ - **`LineMark`**: separate lines with `.foregroundStyle(by:)` or the
83
+ `series:` parameter; smooth with `.interpolationMethod(.catmullRom)`.
84
+ - **`PointMark`**: combine with `.foregroundStyle(by:)`, `.symbol(by:)` and
85
+ `.symbolSize(100)`.
86
+ - **`AreaMark`**: stacks with `.foregroundStyle(by:)`;
87
+ `AreaMark(x:yStart:yEnd:)` draws a band, usually with `.opacity(0.3)`.
88
+ - **`RuleMark`**: a threshold line.
143
89
 
144
90
  ```swift
145
- RuleMark(y: .value("Target", 9000))
146
- .foregroundStyle(.red)
147
- .lineStyle(StrokeStyle(dash: [5, 3]))
91
+ RuleMark(y: .value("Goal", 10_000))
92
+ .lineStyle(StrokeStyle(lineWidth: 1.5, dash: [6, 4]))
148
93
  .annotation(position: .top, alignment: .leading) {
149
- Text("Target").font(.caption).foregroundStyle(.red)
94
+ Text("Daily goal").font(.caption)
150
95
  }
151
96
  ```
152
97
 
153
- ### RectangleMark (iOS 16+)
98
+ - **`RectangleMark(x:y:)`** with `.foregroundStyle(by:)`: the cells of a heat
99
+ map.
100
+ - **`SectorMark`** (iOS 17): the slices of pies and donuts. Every value has
101
+ to be above zero; drop, combine or footnote any zero or negative entries
102
+ before they reach the chart.
154
103
 
155
104
  ```swift
156
- RectangleMark(x: .value("Hour", item.hour), y: .value("Day", item.day))
157
- .foregroundStyle(by: .value("Intensity", item.intensity))
158
- ```
159
-
160
- ### SectorMark (iOS 17+)
161
- Use `SectorMark` for strictly positive values; filter, aggregate, or explain zero/negative values outside the pie or donut.
162
- ```swift
163
- // Pie chart
164
- Chart(data, id: \.name) { item in
165
- SectorMark(angle: .value("Sales", item.sales))
166
- .foregroundStyle(by: .value("Category", item.name))
167
- }
168
-
169
- // Donut chart
170
- Chart(data, id: \.name) { item in
171
- SectorMark(
172
- angle: .value("Sales", item.sales),
173
- innerRadius: .ratio(0.618),
174
- outerRadius: .inset(10),
175
- angularInset: 1
176
- )
177
- .cornerRadius(4)
178
- .foregroundStyle(by: .value("Category", item.name))
105
+ Chart(budget) { item in
106
+ SectorMark(angle: .value("Amount", item.amount),
107
+ innerRadius: .ratio(0.618),
108
+ outerRadius: .inset(10),
109
+ angularInset: 1)
110
+ .cornerRadius(4)
111
+ .foregroundStyle(by: .value("Envelope", item.envelope))
179
112
  }
180
113
  ```
181
114
 
182
- ## Axis Customization
183
-
184
- ```swift
185
- // Hide axes
186
- .chartXAxis(.hidden)
187
- .chartYAxis(.hidden)
115
+ Drop `innerRadius` and `angularInset` for a plain pie:
116
+ `SectorMark(angle:)` plus `.foregroundStyle(by:)`.
188
117
 
189
- // Custom axis content
190
- .chartXAxis {
191
- AxisMarks(values: .stride(by: .month)) { value in
192
- AxisGridLine()
193
- AxisTick()
194
- AxisValueLabel(format: .dateTime.month(.abbreviated))
195
- }
196
- }
118
+ ## Axes
197
119
 
198
- // Multiple AxisMarks compositions (different intervals for grid vs. labels)
120
+ ```swift
199
121
  .chartXAxis {
200
122
  AxisMarks(values: .stride(by: .day)) { _ in AxisGridLine() }
201
- AxisMarks(values: .stride(by: .week)) { _ in
123
+ AxisMarks(values: .stride(by: .weekOfYear)) { _ in
202
124
  AxisTick()
203
125
  AxisValueLabel(format: .dateTime.week())
204
126
  }
205
127
  }
206
-
207
- // Axis labels (titles)
208
- .chartXAxisLabel("Time", position: .bottom, alignment: .center)
209
- .chartYAxisLabel("Revenue ($)", position: .leading, alignment: .center)
128
+ .chartYAxis(.hidden)
129
+ .chartXAxisLabel("Date", position: .bottom, alignment: .center)
210
130
  ```
211
131
 
212
- ## Scale Configuration
132
+ - `.chartXAxis(.hidden)` and `.chartYAxis(.hidden)` remove an axis.
133
+ - A single `AxisMarks(values: .stride(by: .month))` with `AxisGridLine()`,
134
+ `AxisTick()` and `AxisValueLabel(format: .dateTime.month(.abbreviated))` is
135
+ the common monthly axis.
136
+ - Several `AxisMarks` in one builder give grid lines and labels different
137
+ intervals, as above.
138
+ - Titles: `.chartXAxisLabel(_:position:alignment:)` and
139
+ `.chartYAxisLabel("Steps", position: .leading, alignment: .center)`.
140
+
141
+ ## Scales
213
142
 
214
143
  ```swift
215
- .chartYScale(domain: 0...100) // Explicit numeric domain
216
- .chartYScale(domain: .automatic(includesZero: true)) // Include zero
217
- .chartYScale(domain: 1...10000, type: .log) // Logarithmic scale
218
- .chartXScale(domain: ["Mon", "Tue", "Wed", "Thu"]) // Categorical ordering
144
+ .chartYScale(domain: 0...100)
145
+ .chartYScale(domain: .automatic(includesZero: true))
146
+ .chartYScale(domain: 1...10_000, type: .log)
147
+ .chartXScale(domain: ["Small", "Medium", "Large", "XL"])
219
148
  ```
220
149
 
221
- ## Foreground Style and Encoding
150
+ A numeric range fixes the domain, `.automatic(includesZero: true)` keeps zero
151
+ in view, `type: .log` gives a log scale, and an array of categories sets their
152
+ order.
153
+
154
+ ## Colour and Encoding
222
155
 
223
156
  ```swift
224
- BarMark(...).foregroundStyle(.blue) // Static color
225
- BarMark(...).foregroundStyle(by: .value("Category", item.category)) // Data encoding
226
- AreaMark(...).foregroundStyle( // Gradient
227
- .linearGradient(colors: [.blue, .cyan], startPoint: .bottom, endPoint: .top)
228
- )
157
+ .foregroundStyle(.teal)
158
+ .foregroundStyle(by: .value("Region", item.region))
159
+ .foregroundStyle(.linearGradient(colors: [.teal, .blue],
160
+ startPoint: .bottom, endPoint: .top))
229
161
  ```
230
162
 
231
- ## Selection (iOS 17+)
163
+ A fixed style, a style driven by data, and a gradient.
164
+
165
+ ## Selection (iOS 17)
232
166
 
233
167
  ```swift
234
- @State private var selectedDate: Date?
235
- @State private var selectedRange: ClosedRange<Date>?
236
- @State private var selectedAngle: Double?
168
+ @State private var pickedDay: Date?
169
+ @State private var pickedWeek: ClosedRange<Date>?
170
+ @State private var pickedAngle: Double?
237
171
 
238
- // Point selection
239
- Chart(data) { item in
240
- LineMark(x: .value("Date", item.date), y: .value("Value", item.value))
241
- }
242
- .chartXSelection(value: $selectedDate)
172
+ Chart(days) { BarMark(x: .value("Date", $0.date, unit: .day), y: .value("Steps", $0.count)) }
173
+ .chartXSelection(value: $pickedDay)
243
174
 
244
- // Range selection
245
- .chartXSelection(range: $selectedRange)
175
+ Chart(days) { BarMark(x: .value("Date", $0.date, unit: .day), y: .value("Steps", $0.count)) }
176
+ .chartXSelection(range: $pickedWeek)
246
177
 
247
- // Angular selection binds the plottable angle value; derive the category from ranges.
248
- .chartAngleSelection(value: $selectedAngle)
178
+ Chart(budget) { SectorMark(angle: .value("Amount", $0.amount)) }
179
+ .chartAngleSelection(value: $pickedAngle)
249
180
  ```
250
181
 
251
- ## Scrollable Charts (iOS 17+)
182
+ `chartAngleSelection` hands back a position along the cumulative angle value,
183
+ not a category. Walk the sectors and add up their values to find which one
184
+ contains it; the patterns file has a full example.
185
+
186
+ ## Scrolling (iOS 17)
252
187
 
253
188
  ```swift
254
- Chart(dailyData) { item in
255
- BarMark(x: .value("Date", item.date, unit: .day), y: .value("Steps", item.steps))
189
+ Chart(readings) { reading in
190
+ LineMark(x: .value("Time", reading.date, unit: .day),
191
+ y: .value("Level", reading.level))
256
192
  }
257
193
  .chartScrollableAxes(.horizontal)
258
- .chartXVisibleDomain(length: 3600 * 24 * 7) // 7 days visible
259
- .chartScrollPosition(initialX: latestDate)
194
+ .chartXVisibleDomain(length: 3600 * 24 * 7)
195
+ .chartScrollPosition(initialX: newestDate)
260
196
  .chartScrollTargetBehavior(
261
- .valueAligned(matching: DateComponents(hour: 0), majorAlignment: .page)
262
- )
197
+ .valueAligned(matching: DateComponents(hour: 0),
198
+ majorAlignment: .page))
263
199
  ```
264
200
 
201
+ For a date axis the visible length is in seconds; this shows one week.
202
+ `valueAligned` snaps to midnight and pages by the visible width. Bucket dates
203
+ with `unit:` as in `.value("Time", reading.date, unit: .day)`.
204
+
265
205
  ## Annotations
266
206
 
267
207
  ```swift
268
- BarMark(x: .value("Month", item.month), y: .value("Sales", item.sales))
269
- .annotation(position: .top, alignment: .center, spacing: 4) {
270
- Text("\(item.sales, format: .number)").font(.caption2)
208
+ BarMark(x: .value("Quarter", row.quarter), y: .value("Orders", row.orders))
209
+ .annotation(position: .top, alignment: .center, spacing: 6) {
210
+ Text(row.orders, format: .number.notation(.compactName))
271
211
  }
272
-
273
- // Overflow resolution
274
- .annotation(
275
- position: .top,
276
- overflowResolution: .init(x: .fit(to: .chart), y: .padScale)
277
- ) { Text("Label") }
278
212
  ```
279
213
 
214
+ When annotations near the edge get cut off:
215
+ `.annotation(position: .top, overflowResolution: .init(x: .fit(to: .chart), y: .disabled))`,
216
+ or `y: .padScale` to grow the scale so the annotation fits.
217
+
280
218
  ## Legend
281
219
 
282
220
  ```swift
283
- .chartLegend(.hidden) // Hide
284
- .chartLegend(position: .bottom, alignment: .center, spacing: 10) // Position
285
- .chartLegend(position: .bottom) { // Custom
286
- HStack {
287
- ForEach(categories, id: \.self) { cat in
288
- Label(cat, systemImage: "circle.fill").font(.caption)
289
- }
290
- }
291
- }
221
+ .chartLegend(.hidden)
222
+ .chartLegend(position: .top, alignment: .leading, spacing: 8)
223
+ .chartLegend(position: .bottom) { RegionLegend(regions: regions) }
292
224
  ```
293
225
 
294
- ## Vectorized Plots (iOS 18+)
226
+ ## Vectorized Plots (iOS 18)
295
227
 
296
- Use for large datasets (1000+ points). Accept entire collections or functions.
228
+ For about 1,000 points or more. They take a whole collection, or a function.
297
229
 
298
230
  ```swift
299
- // Data-driven
300
231
  Chart {
301
- BarPlot(sales, x: .value("Month", \.month), y: .value("Revenue", \.revenue))
302
- .foregroundStyle(\.barColor)
232
+ BarPlot(hourly, x: .value("Hour", \.hour), y: .value("Requests", \.requests))
233
+ .foregroundStyle(\.tint)
234
+ .opacity(0.9)
303
235
  }
304
236
 
305
- // Function plotting: y = f(x)
306
237
  Chart {
307
- LinePlot(x: "x", y: "y", domain: -5...5) { x in sin(x) }
238
+ LinePlot(x: "Input", y: "Output", domain: -3...3) { x in x * x * x - 4 * x }
308
239
  }
309
240
 
310
- // Parametric: (x, y) = f(t)
311
241
  Chart {
312
- LinePlot(x: "x", y: "y", t: "t", domain: 0...(2 * .pi)) { t in
313
- (x: cos(t), y: sin(t))
242
+ LinePlot(x: "East", y: "North", t: "Phase", domain: 0...(2 * .pi)) { phase in
243
+ (x: cos(3 * phase), y: sin(2 * phase))
314
244
  }
315
245
  }
316
246
  ```
317
247
 
318
- Apply KeyPath-based modifiers before simple-value modifiers:
248
+ Modifiers that take a key path must come before modifiers that take a plain
249
+ value; the other order does not compile.
319
250
 
320
- ```swift
321
- BarPlot(data, x: .value("X", \.x), y: .value("Y", \.y))
322
- .foregroundStyle(\.color) // KeyPath first
323
- .opacity(0.8) // Value modifier second
324
- ```
251
+ ## 3D Charts (iOS 26)
325
252
 
326
- ## 3D Charts (iOS 26+)
327
-
328
- Use `Chart3D` for spatial data or bivariate surfaces, not as a decorative
329
- replacement for ordinary 2D categorical or time-series charts. `Chart3D`
330
- accepts `SurfacePlot` plus 3D initializers of `PointMark`, `RuleMark`, and
331
- `RectangleMark`.
253
+ Use `Chart3D` for data with three real spatial dimensions or a surface of two
254
+ variables. Do not use it to decorate ordinary category or time-series data.
255
+ `Chart3D` accepts `SurfacePlot` and the 3D initialisers of `PointMark`,
256
+ `RuleMark` and `RectangleMark`.
332
257
 
333
258
  ```swift
334
- @State private var pose: Chart3DPose = .default
335
-
336
- Chart3D {
337
- SurfacePlot(x: "x", y: "y", z: "z") { x, z in
338
- sin(2 * x) * cos(2 * z)
259
+ struct TerrainChart: View {
260
+ @State private var viewAngle: Chart3DPose = .default
261
+
262
+ var body: some View {
263
+ Chart3D {
264
+ SurfacePlot(x: "Longitude", y: "Elevation", z: "Latitude") { x, z in
265
+ sin(x) * cos(z)
266
+ }
267
+ .foregroundStyle(.heightBased)
268
+ }
269
+ .chartXScale(domain: -3...3)
270
+ .chartYScale(domain: -1...1)
271
+ .chartZScale(domain: -3...3)
272
+ .chart3DPose($viewAngle)
339
273
  }
340
- .foregroundStyle(.heightBased)
341
274
  }
342
- .chartXScale(domain: -2...2)
343
- .chartYScale(domain: -1...1)
344
- .chartZScale(domain: -2...2)
345
- .chart3DPose($pose)
346
275
  ```
347
276
 
348
277
  ## Common Mistakes
349
278
 
350
- ### 1. Missing series parameter for multi-line charts
351
-
352
- ```swift
353
- // WRONG -- all points connect into one line
354
- Chart {
355
- ForEach(allCities) { item in
356
- LineMark(x: .value("Date", item.date), y: .value("Temp", item.temp))
357
- }
358
- }
359
-
360
- // CORRECT -- separate lines per city
361
- Chart {
362
- ForEach(allCities) { item in
363
- LineMark(x: .value("Date", item.date), y: .value("Temp", item.temp))
364
- .foregroundStyle(by: .value("City", item.city))
365
- }
366
- }
367
- ```
368
-
369
- ### 2. Too many SectorMark slices
370
-
371
- ```swift
372
- // WRONG -- 20 tiny sectors are unreadable
373
- Chart(twentyCategories, id: \.name) { item in
374
- SectorMark(angle: .value("Value", item.value))
375
- }
376
-
377
- // CORRECT -- group into top 5 + "Other"
378
- Chart(groupedData, id: \.name) { item in
379
- SectorMark(angle: .value("Value", item.value))
380
- .foregroundStyle(by: .value("Category", item.name))
381
- }
382
- ```
383
-
384
- ### 3. Missing scale domain when zero-baseline matters
385
-
386
- ```swift
387
- // WRONG -- axis starts at ~95; small changes look dramatic
388
- Chart(data) {
389
- LineMark(x: .value("Day", $0.day), y: .value("Score", $0.score))
390
- }
391
-
392
- // CORRECT -- explicit domain for honest representation
393
- Chart(data) {
394
- LineMark(x: .value("Day", $0.day), y: .value("Score", $0.score))
395
- }
396
- .chartYScale(domain: 0...100)
397
- ```
398
-
399
- ### 4. Static foregroundStyle overriding data encoding
400
-
401
- ```swift
402
- // WRONG -- static color overrides by-value encoding
403
- BarMark(x: .value("X", item.x), y: .value("Y", item.y))
404
- .foregroundStyle(by: .value("Category", item.category))
405
- .foregroundStyle(.blue)
406
-
407
- // CORRECT -- use only the data encoding
408
- BarMark(x: .value("X", item.x), y: .value("Y", item.y))
409
- .foregroundStyle(by: .value("Category", item.category))
410
- ```
411
-
412
- ### 5. Individual marks for 10,000+ data points
413
-
414
- ```swift
415
- // WRONG -- creates 10,000 mark views; slow
416
- Chart(largeDataset) { item in
417
- PointMark(x: .value("X", item.x), y: .value("Y", item.y))
418
- }
419
-
420
- // CORRECT -- vectorized plot (iOS 18+)
421
- Chart {
422
- PointPlot(largeDataset, x: .value("X", \.x), y: .value("Y", \.y))
423
- }
424
- ```
425
-
426
- ### 6. Fixed chart height breaking Dynamic Type
427
-
428
- ```swift
429
- // WRONG -- clips axis labels at large text sizes
430
- Chart(data) { ... }
431
- .frame(height: 200)
432
-
433
- // CORRECT -- adaptive sizing
434
- Chart(data) { ... }
435
- .frame(minHeight: 200, maxHeight: 400)
436
- ```
437
-
438
- ### 7. KeyPath modifier after value modifier on vectorized plots
439
-
440
- ```swift
441
- // WRONG -- compiler error
442
- BarPlot(data, x: .value("X", \.x), y: .value("Y", \.y))
443
- .opacity(0.8)
444
- .foregroundStyle(\.color)
445
-
446
- // CORRECT -- KeyPath modifiers first
447
- BarPlot(data, x: .value("X", \.x), y: .value("Y", \.y))
448
- .foregroundStyle(\.color)
449
- .opacity(0.8)
450
- ```
451
-
452
- ### 8. Missing accessibility labels
453
-
454
- ```swift
455
- // WRONG -- VoiceOver users get no context
456
- Chart(data) {
457
- BarMark(x: .value("Month", $0.month), y: .value("Sales", $0.sales))
458
- }
459
-
460
- // CORRECT -- add per-mark accessibility
461
- Chart(data) { item in
462
- BarMark(x: .value("Month", item.month), y: .value("Sales", item.sales))
463
- .accessibilityLabel("\(item.month)")
464
- .accessibilityValue("\(item.sales) units sold")
465
- }
466
- ```
467
-
468
- ### 9. Treating angle selection as category selection
469
-
470
- `chartAngleSelection(value:)` binds the selected plottable angle value. For
471
- pie and donut charts, map that numeric value through cumulative sector ranges
472
- before comparing it to a category label.
279
+ | Mistake | Fix |
280
+ |---------|-----|
281
+ | Several series drawn as one zig-zag line | Add `.foregroundStyle(by:)` or `series:` |
282
+ | A pie with 20 slices | Keep the top five and group the rest as "Other" |
283
+ | No explicit domain where the zero baseline matters, so small changes look huge | `.chartYScale(domain: 0...100)` or `includesZero` |
284
+ | `.foregroundStyle(.blue)` after `.foregroundStyle(by:)` | The fixed style overrides the encoding; keep only the encoding |
285
+ | 10,000 individual marks | `PointPlot` and the other vectorized plots (iOS 18) |
286
+ | `.frame(height: 200)` clipping axis labels at large Dynamic Type sizes | `.frame(minHeight: 200, maxHeight: 400)` |
287
+ | A plain-value modifier before a key-path modifier on a vectorized plot | Put key-path modifiers first |
288
+ | No accessibility on marks | `.accessibilityLabel` and `.accessibilityValue` per mark |
289
+ | Comparing the `chartAngleSelection` value with a category name | Map the angle through cumulative sector ranges first |
473
290
 
474
291
  ## Review Checklist
475
292
 
476
- - [ ] Data model uses `Identifiable` or chart uses `id:` key path
477
- - [ ] Mark type matches goal (bar=comparison, line=trend, sector=proportion)
478
- - [ ] Multi-series lines use `series:` parameter or `.foregroundStyle(by:)`
479
- - [ ] Axes configured with appropriate labels, ticks, and grid lines
480
- - [ ] Scale domain set explicitly when zero-baseline matters
481
- - [ ] Pie/donut uses positive values, 5-7 sectors, and "Other" grouping
482
- - [ ] Selection binding type matches axis data type (`Date?` for date axis)
483
- - [ ] Pie/donut angle selection maps numeric angle values back to categories
484
- - [ ] Scrollable charts set `.chartXVisibleDomain(length:)` for viewport
485
- - [ ] Vectorized plots used for datasets exceeding 1000 points
486
- - [ ] KeyPath modifiers applied before value modifiers on vectorized plots
487
- - [ ] `Chart3D` used only for real 3D data or surfaces, with z scale and pose reviewed
488
- - [ ] Accessibility labels added to marks for VoiceOver
489
- - [ ] Chart tested with Dynamic Type and Dark Mode
490
- - [ ] Legend visible and positioned, or intentionally hidden
491
- - [ ] Ensure chart data model types are Sendable; update chart data on @MainActor
492
-
493
- ## References
494
-
495
- - Extended patterns: [references/charts-patterns.md](references/charts-patterns.md)
496
- - Apple docs: [Swift Charts](https://sosumi.ai/documentation/charts)
497
- - Apple docs: [Creating a chart using Swift Charts](https://sosumi.ai/documentation/charts/Creating-a-chart-using-Swift-Charts)
498
- - Apple docs: [Swift Charts updates](https://sosumi.ai/documentation/updates/swiftcharts)
499
- - Apple docs: [Chart3D](https://sosumi.ai/documentation/charts/Chart3D)
500
- - Apple docs: [SurfacePlot](https://sosumi.ai/documentation/charts/SurfacePlot)
293
+ - [ ] Data is `Identifiable` or has an `id:` key path
294
+ - [ ] The mark suits the question: bars compare, lines show trends, sectors show shares
295
+ - [ ] Multi-series lines use `series:` or `.foregroundStyle(by:)`
296
+ - [ ] Axes have suitable labels, ticks and grid lines
297
+ - [ ] An explicit domain where the zero baseline matters
298
+ - [ ] Pies and donuts: positive values, five to seven slices, an "Other" group
299
+ - [ ] Selection bindings match the axis type (`Date?` for a date axis)
300
+ - [ ] Angle selection is mapped back to a category
301
+ - [ ] Scrollable charts set `.chartXVisibleDomain(length:)`
302
+ - [ ] Vectorized plots for more than about 1,000 points, key-path modifiers first
303
+ - [ ] `Chart3D` reserved for genuine spatial data or surfaces; z domain and pose reviewed
304
+ - [ ] Marks carry accessibility labels; checked at large text sizes and in Dark Mode
305
+ - [ ] The legend is visible and placed, or hidden on purpose
306
+ - [ ] Chart data types are `Sendable`, and chart data is updated on the main actor
307
+
308
+ ## Apple Documentation
309
+
310
+ - [Swift Charts](https://developer.apple.com/documentation/charts)
311
+ - [Building a first chart](https://developer.apple.com/documentation/charts/creating-a-chart-using-swift-charts)
312
+ - [Swift Charts updates](https://developer.apple.com/documentation/updates/swiftcharts)
313
+ - [Chart3D](https://developer.apple.com/documentation/charts/chart3d)
314
+ - [SurfacePlot](https://developer.apple.com/documentation/charts/surfaceplot)