@mmerterden/multi-agent-pipeline 20.6.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.
Files changed (326) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/LICENSE +0 -10
  3. package/docs/facts.json +1 -1
  4. package/manifest.json +328 -329
  5. package/package.json +2 -2
  6. package/pipeline/multi-agent-refs/features/design-conformance.md +62 -64
  7. package/pipeline/scripts/_notices.mjs +12 -1
  8. package/pipeline/scripts/gen-skills-index.mjs +1 -1
  9. package/pipeline/skills/.skill-manifest.json +106 -106
  10. package/pipeline/skills/shared/README.md +71 -71
  11. package/pipeline/skills/shared/external/agent-introspection-debugging/SKILL.md +1 -0
  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/android-architecture/SKILL.md +2 -0
  16. package/pipeline/skills/shared/external/android-performance/SKILL.md +2 -0
  17. package/pipeline/skills/shared/external/android-security/SKILL.md +2 -0
  18. package/pipeline/skills/shared/external/app-clips/SKILL.md +260 -160
  19. package/pipeline/skills/shared/external/app-clips/evals/evals.json +27 -27
  20. package/pipeline/skills/shared/external/app-clips/references/data-handoff-notifications-location.md +150 -83
  21. package/pipeline/skills/shared/external/app-clips/references/routing-and-experiences.md +135 -83
  22. package/pipeline/skills/shared/external/app-clips/references/size-capabilities-and-promotion.md +143 -85
  23. package/pipeline/skills/shared/external/app-intents/SKILL.md +302 -304
  24. package/pipeline/skills/shared/external/app-intents/evals/evals.json +21 -21
  25. package/pipeline/skills/shared/external/app-intents/references/appintents-advanced.md +594 -894
  26. package/pipeline/skills/shared/external/app-store-optimization/SKILL.md +339 -277
  27. package/pipeline/skills/shared/external/app-store-optimization/evals/evals.json +27 -23
  28. package/pipeline/skills/shared/external/app-store-optimization/references/keyword-research-methodology.md +105 -122
  29. package/pipeline/skills/shared/external/app-store-optimization/references/product-page-variants.md +143 -166
  30. package/pipeline/skills/shared/external/app-store-review/SKILL.md +307 -326
  31. package/pipeline/skills/shared/external/app-store-review/evals/evals.json +21 -21
  32. package/pipeline/skills/shared/external/app-store-review/references/privacy-manifest.md +105 -67
  33. package/pipeline/skills/shared/external/app-store-review/references/review-checklists.md +114 -101
  34. package/pipeline/skills/shared/external/apple-on-device-ai/SKILL.md +333 -360
  35. package/pipeline/skills/shared/external/apple-on-device-ai/evals/evals.json +24 -27
  36. package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-conversion.md +215 -322
  37. package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-optimization.md +161 -256
  38. package/pipeline/skills/shared/external/apple-on-device-ai/references/foundation-models.md +277 -387
  39. package/pipeline/skills/shared/external/apple-on-device-ai/references/mlx-swift.md +196 -210
  40. package/pipeline/skills/shared/external/authentication/SKILL.md +265 -381
  41. package/pipeline/skills/shared/external/authentication/evals/evals.json +25 -25
  42. package/pipeline/skills/shared/external/authentication/references/keychain-biometric.md +133 -178
  43. package/pipeline/skills/shared/external/authentication/references/passkeys.md +111 -147
  44. package/pipeline/skills/shared/external/avkit/SKILL.md +267 -364
  45. package/pipeline/skills/shared/external/avkit/evals/evals.json +26 -26
  46. package/pipeline/skills/shared/external/avkit/references/avkit-patterns.md +375 -493
  47. package/pipeline/skills/shared/external/background-processing/SKILL.md +270 -382
  48. package/pipeline/skills/shared/external/background-processing/evals/evals.json +22 -22
  49. package/pipeline/skills/shared/external/background-processing/references/background-task-patterns.md +169 -317
  50. package/pipeline/skills/shared/external/backlog/BACKLOG.md +1 -1
  51. package/pipeline/skills/shared/external/backlog/SKILL.md +56 -33
  52. package/pipeline/skills/shared/external/callkit-voip/SKILL.md +290 -371
  53. package/pipeline/skills/shared/external/callkit-voip/evals/evals.json +24 -24
  54. package/pipeline/skills/shared/external/callkit-voip/references/callkit-patterns.md +175 -343
  55. package/pipeline/skills/shared/external/ci-cd-pipelines/SKILL.md +1 -0
  56. package/pipeline/skills/shared/external/cloudkit-sync/SKILL.md +292 -381
  57. package/pipeline/skills/shared/external/cloudkit-sync/evals/evals.json +33 -30
  58. package/pipeline/skills/shared/external/cloudkit-sync/references/cloudkit-patterns.md +227 -355
  59. package/pipeline/skills/shared/external/compose-components/SKILL.md +2 -0
  60. package/pipeline/skills/shared/external/compose-navigation/SKILL.md +3 -2
  61. package/pipeline/skills/shared/external/compose-testing/SKILL.md +2 -0
  62. package/pipeline/skills/shared/external/contacts-framework/SKILL.md +197 -346
  63. package/pipeline/skills/shared/external/contacts-framework/evals/evals.json +19 -21
  64. package/pipeline/skills/shared/external/contacts-framework/references/contacts-patterns.md +169 -308
  65. package/pipeline/skills/shared/external/core-bluetooth/SKILL.md +226 -376
  66. package/pipeline/skills/shared/external/core-bluetooth/evals/evals.json +25 -22
  67. package/pipeline/skills/shared/external/core-bluetooth/references/ble-patterns.md +257 -337
  68. package/pipeline/skills/shared/external/core-data/SKILL.md +292 -368
  69. package/pipeline/skills/shared/external/core-data/evals/evals.json +30 -27
  70. package/pipeline/skills/shared/external/core-motion/SKILL.md +235 -324
  71. package/pipeline/skills/shared/external/core-motion/evals/evals.json +31 -27
  72. package/pipeline/skills/shared/external/core-motion/references/motion-patterns.md +210 -310
  73. package/pipeline/skills/shared/external/core-nfc/SKILL.md +292 -366
  74. package/pipeline/skills/shared/external/core-nfc/evals/evals.json +22 -24
  75. package/pipeline/skills/shared/external/core-nfc/references/nfc-patterns.md +233 -329
  76. package/pipeline/skills/shared/external/coreml/SKILL.md +323 -367
  77. package/pipeline/skills/shared/external/coreml/evals/evals.json +24 -21
  78. package/pipeline/skills/shared/external/coreml/references/coreml-swift-integration.md +562 -565
  79. package/pipeline/skills/shared/external/council/SKILL.md +1 -0
  80. package/pipeline/skills/shared/external/cryptokit/SKILL.md +253 -394
  81. package/pipeline/skills/shared/external/cryptokit/evals/evals.json +20 -18
  82. package/pipeline/skills/shared/external/cryptokit/references/cryptokit-patterns.md +299 -488
  83. package/pipeline/skills/shared/external/css-modern/SKILL.md +1 -0
  84. package/pipeline/skills/shared/external/database-patterns/SKILL.md +1 -0
  85. package/pipeline/skills/shared/external/debugging-instruments/SKILL.md +270 -323
  86. package/pipeline/skills/shared/external/debugging-instruments/evals/evals.json +27 -30
  87. package/pipeline/skills/shared/external/debugging-instruments/references/instruments-guide.md +167 -315
  88. package/pipeline/skills/shared/external/debugging-instruments/references/lldb-patterns.md +140 -193
  89. package/pipeline/skills/shared/external/device-integrity/SKILL.md +230 -353
  90. package/pipeline/skills/shared/external/device-integrity/evals/evals.json +25 -21
  91. package/pipeline/skills/shared/external/device-integrity/references/device-integrity-patterns.md +159 -197
  92. package/pipeline/skills/shared/external/energykit/SKILL.md +225 -392
  93. package/pipeline/skills/shared/external/energykit/evals/evals.json +29 -28
  94. package/pipeline/skills/shared/external/energykit/references/energykit-patterns.md +174 -470
  95. package/pipeline/skills/shared/external/eventkit-calendar/SKILL.md +261 -383
  96. package/pipeline/skills/shared/external/eventkit-calendar/evals/evals.json +25 -22
  97. package/pipeline/skills/shared/external/eventkit-calendar/references/eventkit-patterns.md +165 -268
  98. package/pipeline/skills/shared/external/evidence-github/SKILL.md +2 -0
  99. package/pipeline/skills/shared/external/evidence-registry/SKILL.md +2 -0
  100. package/pipeline/skills/shared/external/gradle-kotlin-dsl/SKILL.md +2 -0
  101. package/pipeline/skills/shared/external/healthkit/SKILL.md +252 -303
  102. package/pipeline/skills/shared/external/healthkit/evals/evals.json +24 -23
  103. package/pipeline/skills/shared/external/healthkit/references/healthkit-patterns.md +369 -523
  104. package/pipeline/skills/shared/external/homekit-matter/SKILL.md +233 -348
  105. package/pipeline/skills/shared/external/homekit-matter/evals/evals.json +27 -22
  106. package/pipeline/skills/shared/external/homekit-matter/references/matter-commissioning.md +199 -305
  107. package/pipeline/skills/shared/external/html-semantic/SKILL.md +1 -0
  108. package/pipeline/skills/shared/external/humanizer/SKILL.md +1 -0
  109. package/pipeline/skills/shared/external/ios-accessibility/SKILL.md +368 -340
  110. package/pipeline/skills/shared/external/ios-accessibility/evals/evals.json +28 -27
  111. package/pipeline/skills/shared/external/ios-accessibility/references/a11y-patterns.md +314 -260
  112. package/pipeline/skills/shared/external/ios-accessibility/references/media-accessibility.md +97 -67
  113. package/pipeline/skills/shared/external/ios-accessibility/references/nutrition-labels.md +165 -101
  114. package/pipeline/skills/shared/external/ios-coding-standard/SKILL.md +1 -0
  115. package/pipeline/skills/shared/external/ios-localization/SKILL.md +258 -371
  116. package/pipeline/skills/shared/external/ios-localization/evals/evals.json +23 -23
  117. package/pipeline/skills/shared/external/ios-localization/references/formatstyle-locale.md +283 -491
  118. package/pipeline/skills/shared/external/ios-localization/references/string-catalogs.md +313 -440
  119. package/pipeline/skills/shared/external/ios-module-structure/SKILL.md +1 -0
  120. package/pipeline/skills/shared/external/ios-networking/SKILL.md +265 -341
  121. package/pipeline/skills/shared/external/ios-networking/evals/evals.json +24 -24
  122. package/pipeline/skills/shared/external/ios-networking/references/background-websocket.md +425 -652
  123. package/pipeline/skills/shared/external/ios-networking/references/file-storage-patterns.md +143 -285
  124. package/pipeline/skills/shared/external/ios-networking/references/lightweight-clients.md +93 -53
  125. package/pipeline/skills/shared/external/ios-networking/references/network-framework.md +231 -456
  126. package/pipeline/skills/shared/external/ios-networking/references/urlsession-patterns.md +517 -784
  127. package/pipeline/skills/shared/external/ios-security/SKILL.md +2 -0
  128. package/pipeline/skills/shared/external/ios-simulator/SKILL.md +265 -393
  129. package/pipeline/skills/shared/external/ios-simulator/evals/evals.json +21 -21
  130. package/pipeline/skills/shared/external/ios-simulator/references/simctl-commands.md +177 -270
  131. package/pipeline/skills/shared/external/live-activities/SKILL.md +318 -360
  132. package/pipeline/skills/shared/external/live-activities/evals/evals.json +21 -21
  133. package/pipeline/skills/shared/external/live-activities/references/activitykit-patterns.md +478 -710
  134. package/pipeline/skills/shared/external/localization-reuse-map/SKILL.md +91 -283
  135. package/pipeline/skills/shared/external/localization-reuse-map/reference/format-and-output.md +119 -151
  136. package/pipeline/skills/shared/external/localization-reuse-map/reference/publish-and-snapshot.md +60 -90
  137. package/pipeline/skills/shared/external/localization-reuse-map/reference/sources-and-recipes.md +119 -156
  138. package/pipeline/skills/shared/external/localization-reuse-map/scripts/build-artifact.py +726 -787
  139. package/pipeline/skills/shared/external/localization-reuse-map/scripts/build-spreadsheet.py +253 -288
  140. package/pipeline/skills/shared/external/localization-reuse-map/scripts/fetch-annotations.py +243 -304
  141. package/pipeline/skills/shared/external/localization-reuse-map/scripts/fetch-legacy-labels.py +88 -104
  142. package/pipeline/skills/shared/external/localization-reuse-map/scripts/publish-confluence.py +181 -235
  143. package/pipeline/skills/shared/external/localization-reuse-map/scripts/render-key-shots.py +198 -263
  144. package/pipeline/skills/shared/external/localization-reuse-map/scripts/render-overlay.py +461 -466
  145. package/pipeline/skills/shared/external/localization-reuse-map/scripts/resolve-legacy-values.py +145 -151
  146. package/pipeline/skills/shared/external/localization-reuse-map/scripts/resolve-new-values.py +123 -141
  147. package/pipeline/skills/shared/external/localization-reuse-map/scripts/scan-screen-keys.py +146 -157
  148. package/pipeline/skills/shared/external/localization-reuse-map/scripts/snapshot-resources.sh +22 -19
  149. package/pipeline/skills/shared/external/localization-reuse-map/scripts/verify-map.py +156 -140
  150. package/pipeline/skills/shared/external/mapkit-location/SKILL.md +295 -267
  151. package/pipeline/skills/shared/external/mapkit-location/evals/evals.json +28 -24
  152. package/pipeline/skills/shared/external/mapkit-location/references/mapkit-corelocation-patterns.md +378 -532
  153. package/pipeline/skills/shared/external/mapkit-location/references/mapkit-patterns.md +397 -499
  154. package/pipeline/skills/shared/external/metrickit-diagnostics/SKILL.md +165 -348
  155. package/pipeline/skills/shared/external/metrickit-diagnostics/evals/evals.json +26 -23
  156. package/pipeline/skills/shared/external/metrickit-diagnostics/references/metrickit-patterns.md +123 -130
  157. package/pipeline/skills/shared/external/musickit-audio/SKILL.md +189 -315
  158. package/pipeline/skills/shared/external/musickit-audio/evals/evals.json +22 -21
  159. package/pipeline/skills/shared/external/musickit-audio/references/musickit-patterns.md +181 -270
  160. package/pipeline/skills/shared/external/natural-language/SKILL.md +188 -340
  161. package/pipeline/skills/shared/external/natural-language/evals/evals.json +21 -21
  162. package/pipeline/skills/shared/external/natural-language/references/translation-patterns.md +171 -225
  163. package/pipeline/skills/shared/external/nextjs-app-router/SKILL.md +1 -0
  164. package/pipeline/skills/shared/external/passkit-wallet/SKILL.md +258 -392
  165. package/pipeline/skills/shared/external/passkit-wallet/evals/evals.json +30 -29
  166. package/pipeline/skills/shared/external/passkit-wallet/references/wallet-passes.md +164 -231
  167. package/pipeline/skills/shared/external/pdfkit/SKILL.md +312 -344
  168. package/pipeline/skills/shared/external/pdfkit/evals/evals.json +19 -19
  169. package/pipeline/skills/shared/external/pdfkit/references/pdfkit-patterns.md +413 -624
  170. package/pipeline/skills/shared/external/pencilkit-drawing/SKILL.md +242 -358
  171. package/pipeline/skills/shared/external/pencilkit-drawing/evals/evals.json +25 -21
  172. package/pipeline/skills/shared/external/pencilkit-drawing/references/pencilkit-patterns.md +161 -226
  173. package/pipeline/skills/shared/external/permissionkit/SKILL.md +282 -400
  174. package/pipeline/skills/shared/external/permissionkit/evals/evals.json +27 -30
  175. package/pipeline/skills/shared/external/permissionkit/references/permissionkit-patterns.md +237 -350
  176. package/pipeline/skills/shared/external/photos-camera-media/SKILL.md +276 -325
  177. package/pipeline/skills/shared/external/photos-camera-media/references/av-playback.md +299 -545
  178. package/pipeline/skills/shared/external/photos-camera-media/references/camera-capture.md +344 -588
  179. package/pipeline/skills/shared/external/photos-camera-media/references/image-loading-caching.md +316 -660
  180. package/pipeline/skills/shared/external/photos-camera-media/references/photokit-patterns.md +270 -416
  181. package/pipeline/skills/shared/external/play-store-review/SKILL.md +2 -0
  182. package/pipeline/skills/shared/external/push-notifications/SKILL.md +312 -340
  183. package/pipeline/skills/shared/external/push-notifications/evals/evals.json +27 -26
  184. package/pipeline/skills/shared/external/push-notifications/references/notification-patterns.md +328 -485
  185. package/pipeline/skills/shared/external/push-notifications/references/rich-notifications.md +327 -560
  186. package/pipeline/skills/shared/external/python-patterns/SKILL.md +1 -0
  187. package/pipeline/skills/shared/external/react-best-practices/SKILL.md +1 -0
  188. package/pipeline/skills/shared/external/realitykit-ar/SKILL.md +218 -410
  189. package/pipeline/skills/shared/external/realitykit-ar/evals/evals.json +24 -27
  190. package/pipeline/skills/shared/external/realitykit-ar/references/realitykit-patterns.md +221 -348
  191. package/pipeline/skills/shared/external/rest-api-design/SKILL.md +1 -0
  192. package/pipeline/skills/shared/external/retrofit-networking/SKILL.md +2 -0
  193. package/pipeline/skills/shared/external/room-database/SKILL.md +2 -0
  194. package/pipeline/skills/shared/external/search-first/SKILL.md +1 -0
  195. package/pipeline/skills/shared/external/shareplay-activities/SKILL.md +222 -393
  196. package/pipeline/skills/shared/external/shareplay-activities/evals/evals.json +23 -24
  197. package/pipeline/skills/shared/external/shareplay-activities/references/shareplay-patterns.md +280 -420
  198. package/pipeline/skills/shared/external/signal-community/SKILL.md +2 -0
  199. package/pipeline/skills/shared/external/skill-creator/SKILL.md +80 -41
  200. package/pipeline/skills/shared/external/skill-creator/audit.md +63 -59
  201. package/pipeline/skills/shared/external/skill-creator/checklist.md +28 -20
  202. package/pipeline/skills/shared/external/skill-creator/examples.md +40 -40
  203. package/pipeline/skills/shared/external/skill-creator/label-check.md +48 -36
  204. package/pipeline/skills/shared/external/skill-creator/scripts/audit-panel.js +91 -100
  205. package/pipeline/skills/shared/external/skill-creator/template.md +51 -39
  206. package/pipeline/skills/shared/external/speech-recognition/SKILL.md +217 -421
  207. package/pipeline/skills/shared/external/speech-recognition/evals/evals.json +23 -26
  208. package/pipeline/skills/shared/external/speech-recognition/references/speechanalyzer-patterns.md +133 -125
  209. package/pipeline/skills/shared/external/storekit/SKILL.md +228 -204
  210. package/pipeline/skills/shared/external/storekit/evals/evals.json +27 -24
  211. package/pipeline/skills/shared/external/storekit/references/app-review-guidelines.md +98 -109
  212. package/pipeline/skills/shared/external/storekit/references/core-patterns.md +298 -242
  213. package/pipeline/skills/shared/external/storekit/references/storekit-advanced.md +356 -649
  214. package/pipeline/skills/shared/external/swift-api-design-guidelines/SKILL.md +274 -399
  215. package/pipeline/skills/shared/external/swift-api-design-guidelines/evals/evals.json +22 -24
  216. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/argument-labels-and-parameters.md +107 -108
  217. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/conventions-and-special-rules.md +93 -165
  218. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/naming-and-clarity.md +99 -137
  219. package/pipeline/skills/shared/external/swift-api-design-guidelines/references/side-effects-and-mutating-pairs.md +77 -120
  220. package/pipeline/skills/shared/external/swift-architecture/SKILL.md +334 -350
  221. package/pipeline/skills/shared/external/swift-architecture/evals/evals.json +22 -22
  222. package/pipeline/skills/shared/external/swift-charts/SKILL.md +208 -394
  223. package/pipeline/skills/shared/external/swift-charts/evals/evals.json +27 -30
  224. package/pipeline/skills/shared/external/swift-charts/references/charts-patterns.md +351 -762
  225. package/pipeline/skills/shared/external/swift-codable/SKILL.md +339 -343
  226. package/pipeline/skills/shared/external/swift-codable/evals/evals.json +20 -20
  227. package/pipeline/skills/shared/external/swift-concurrency/SKILL.md +303 -351
  228. package/pipeline/skills/shared/external/swift-concurrency/evals/evals.json +27 -24
  229. package/pipeline/skills/shared/external/swift-concurrency/references/approachable-concurrency.md +65 -80
  230. package/pipeline/skills/shared/external/swift-concurrency/references/async-algorithms.md +48 -84
  231. package/pipeline/skills/shared/external/swift-concurrency/references/bridging-interop.md +134 -79
  232. package/pipeline/skills/shared/external/swift-concurrency/references/concurrency-patterns.md +145 -167
  233. package/pipeline/skills/shared/external/swift-concurrency/references/diagnostics.md +62 -50
  234. package/pipeline/skills/shared/external/swift-concurrency/references/swiftui-concurrency.md +92 -121
  235. package/pipeline/skills/shared/external/swift-concurrency/references/synchronization-primitives.md +177 -241
  236. package/pipeline/skills/shared/external/swift-formatstyle/SKILL.md +258 -234
  237. package/pipeline/skills/shared/external/swift-language/SKILL.md +342 -382
  238. package/pipeline/skills/shared/external/swift-language/evals/evals.json +24 -27
  239. package/pipeline/skills/shared/external/swift-language/references/swift-attributes-interop.md +79 -56
  240. package/pipeline/skills/shared/external/swift-language/references/swift-patterns-extended.md +297 -340
  241. package/pipeline/skills/shared/external/swift-security/SKILL.md +180 -161
  242. package/pipeline/skills/shared/external/swift-security/evals/evals.json +25 -25
  243. package/pipeline/skills/shared/external/swift-security/references/biometric-authentication.md +314 -469
  244. package/pipeline/skills/shared/external/swift-security/references/certificate-trust.md +408 -476
  245. package/pipeline/skills/shared/external/swift-security/references/common-anti-patterns.md +260 -530
  246. package/pipeline/skills/shared/external/swift-security/references/compliance-owasp-mapping.md +270 -477
  247. package/pipeline/skills/shared/external/swift-security/references/credential-storage-patterns.md +573 -571
  248. package/pipeline/skills/shared/external/swift-security/references/cryptokit-public-key.md +370 -441
  249. package/pipeline/skills/shared/external/swift-security/references/cryptokit-symmetric.md +332 -433
  250. package/pipeline/skills/shared/external/swift-security/references/keychain-access-control.md +346 -468
  251. package/pipeline/skills/shared/external/swift-security/references/keychain-fundamentals.md +352 -472
  252. package/pipeline/skills/shared/external/swift-security/references/keychain-item-classes.md +431 -432
  253. package/pipeline/skills/shared/external/swift-security/references/keychain-sharing.md +328 -425
  254. package/pipeline/skills/shared/external/swift-security/references/migration-legacy-stores.md +341 -579
  255. package/pipeline/skills/shared/external/swift-security/references/secure-enclave.md +396 -457
  256. package/pipeline/skills/shared/external/swift-security/references/testing-security-code.md +354 -614
  257. package/pipeline/skills/shared/external/swift-testing/SKILL.md +188 -175
  258. package/pipeline/skills/shared/external/swift-testing/evals/evals.json +26 -24
  259. package/pipeline/skills/shared/external/swift-testing/references/testing-advanced.md +80 -84
  260. package/pipeline/skills/shared/external/swift-testing/references/testing-patterns.md +317 -433
  261. package/pipeline/skills/shared/external/swiftdata/SKILL.md +392 -256
  262. package/pipeline/skills/shared/external/swiftdata/evals/evals.json +24 -24
  263. package/pipeline/skills/shared/external/swiftdata/references/core-data-coexistence.md +206 -402
  264. package/pipeline/skills/shared/external/swiftdata/references/indexing.md +59 -52
  265. package/pipeline/skills/shared/external/swiftdata/references/predicate-pitfalls.md +57 -33
  266. package/pipeline/skills/shared/external/swiftdata/references/swiftdata-advanced.md +354 -747
  267. package/pipeline/skills/shared/external/swiftdata/references/swiftdata-queries.md +300 -508
  268. package/pipeline/skills/shared/external/swiftlint/SKILL.md +175 -226
  269. package/pipeline/skills/shared/external/swiftlint/references/adoption-and-configuration.md +141 -208
  270. package/pipeline/skills/shared/external/swiftlint/references/custom-rules-and-analyze.md +100 -109
  271. package/pipeline/skills/shared/external/swiftlint/references/plugins-run-scripts-and-integrations.md +159 -179
  272. package/pipeline/skills/shared/external/swiftlint/references/rule-reference.md +383 -18
  273. package/pipeline/skills/shared/external/swiftlint/references/rules-suppressions-and-baselines.md +143 -229
  274. package/pipeline/skills/shared/external/swiftui-animation/SKILL.md +283 -366
  275. package/pipeline/skills/shared/external/swiftui-animation/references/animation-advanced.md +396 -608
  276. package/pipeline/skills/shared/external/swiftui-animation/references/core-animation-bridge.md +336 -385
  277. package/pipeline/skills/shared/external/swiftui-gestures/SKILL.md +239 -349
  278. package/pipeline/skills/shared/external/swiftui-gestures/references/gesture-patterns.md +228 -310
  279. package/pipeline/skills/shared/external/swiftui-layout-components/SKILL.md +260 -249
  280. package/pipeline/skills/shared/external/swiftui-layout-components/references/form.md +92 -74
  281. package/pipeline/skills/shared/external/swiftui-layout-components/references/grids.md +112 -177
  282. package/pipeline/skills/shared/external/swiftui-layout-components/references/list.md +61 -64
  283. package/pipeline/skills/shared/external/swiftui-layout-components/references/scrollview.md +94 -134
  284. package/pipeline/skills/shared/external/swiftui-liquid-glass/SKILL.md +193 -225
  285. package/pipeline/skills/shared/external/swiftui-liquid-glass/references/liquid-glass.md +173 -327
  286. package/pipeline/skills/shared/external/swiftui-navigation/SKILL.md +193 -168
  287. package/pipeline/skills/shared/external/swiftui-navigation/references/deeplinks.md +127 -150
  288. package/pipeline/skills/shared/external/swiftui-navigation/references/navigationstack.md +132 -133
  289. package/pipeline/skills/shared/external/swiftui-navigation/references/sheets.md +152 -117
  290. package/pipeline/skills/shared/external/swiftui-navigation/references/tabview.md +106 -140
  291. package/pipeline/skills/shared/external/swiftui-patterns/SKILL.md +316 -252
  292. package/pipeline/skills/shared/external/swiftui-patterns/references/architecture-patterns.md +341 -332
  293. package/pipeline/skills/shared/external/swiftui-patterns/references/deprecated-migration.md +547 -854
  294. package/pipeline/skills/shared/external/swiftui-patterns/references/design-polish.md +485 -537
  295. package/pipeline/skills/shared/external/swiftui-patterns/references/platform-and-sharing.md +417 -499
  296. package/pipeline/skills/shared/external/swiftui-performance/SKILL.md +213 -376
  297. package/pipeline/skills/shared/external/swiftui-performance/references/demystify-swiftui-performance-wwdc23.md +86 -175
  298. package/pipeline/skills/shared/external/swiftui-performance/references/optimizing-swiftui-performance-instruments.md +89 -195
  299. package/pipeline/skills/shared/external/swiftui-performance/references/understanding-hangs-in-your-app.md +95 -182
  300. package/pipeline/skills/shared/external/swiftui-performance/references/understanding-improving-swiftui-performance.md +71 -149
  301. package/pipeline/skills/shared/external/swiftui-performance/references/wwdc-session-sources.md +21 -27
  302. package/pipeline/skills/shared/external/swiftui-uikit-interop/SKILL.md +303 -295
  303. package/pipeline/skills/shared/external/swiftui-uikit-interop/references/hosting-migration.md +204 -387
  304. package/pipeline/skills/shared/external/swiftui-uikit-interop/references/representable-recipes.md +469 -683
  305. package/pipeline/skills/shared/external/swiftui-webkit/SKILL.md +140 -186
  306. package/pipeline/skills/shared/external/swiftui-webkit/references/loading-and-observation.md +75 -86
  307. package/pipeline/skills/shared/external/swiftui-webkit/references/local-content-and-custom-schemes.md +63 -60
  308. package/pipeline/skills/shared/external/swiftui-webkit/references/migration-and-fallbacks.md +69 -137
  309. package/pipeline/skills/shared/external/swiftui-webkit/references/navigation-and-javascript.md +95 -67
  310. package/pipeline/skills/shared/external/tailwind-css/SKILL.md +1 -0
  311. package/pipeline/skills/shared/external/testing-backend/SKILL.md +1 -0
  312. package/pipeline/skills/shared/external/tipkit/SKILL.md +220 -335
  313. package/pipeline/skills/shared/external/tipkit/references/tipkit-patterns.md +356 -494
  314. package/pipeline/skills/shared/external/typescript-patterns/SKILL.md +1 -0
  315. package/pipeline/skills/shared/external/vision-framework/SKILL.md +260 -375
  316. package/pipeline/skills/shared/external/vision-framework/references/vision-requests.md +393 -515
  317. package/pipeline/skills/shared/external/vision-framework/references/visionkit-scanner.md +363 -539
  318. package/pipeline/skills/shared/external/vue-composition/SKILL.md +1 -0
  319. package/pipeline/skills/shared/external/weatherkit/SKILL.md +152 -310
  320. package/pipeline/skills/shared/external/weatherkit/references/weatherkit-patterns.md +288 -407
  321. package/pipeline/skills/shared/external/web-accessibility/SKILL.md +1 -0
  322. package/pipeline/skills/shared/external/web-performance/SKILL.md +1 -0
  323. package/pipeline/skills/shared/external/web-testing/SKILL.md +1 -0
  324. package/pipeline/skills/shared/external/widgetkit/SKILL.md +216 -288
  325. package/pipeline/skills/shared/external/widgetkit/references/widgetkit-advanced.md +414 -719
  326. package/pipeline/skills/shared/external/NOTICE-swift-ios-skills.md +0 -39
@@ -1,87 +1,109 @@
1
1
  ---
2
2
  name: mapkit-location
3
- description: "Implement, review, or improve maps and location features in iOS/macOS apps using MapKit and CoreLocation. Use when working with Map views, annotations, markers, polylines, user location tracking, geocoding, reverse geocoding, search/autocomplete, directions and routes, geofencing, region monitoring, CLLocationUpdate async streams, or location authorization flows. Also use when working with maps, coordinates, addresses, places, directions, distance calculations, or location-based features in Swift apps."
3
+ description: "MapKit and CoreLocation on iOS and macOS: SwiftUI Map, markers, annotations, polylines and overlays, camera control, user location tracking, CLLocationUpdate streams, location authorization, geocoding and reverse geocoding, search and autocomplete, directions, routes and ETA, CLMonitor geofencing and region monitoring, background location, distance math. Use when implementing, reviewing or improving anything built on maps, coordinates, addresses, places, directions or distances."
4
4
  metadata:
5
- source: "dpearson2699/swift-ios-skills (PolyForm Perimeter 1.0.0)"
5
+ source: multi-agent-pipeline
6
6
  ---
7
7
 
8
- # MapKit
8
+ # MapKit and CoreLocation
9
9
 
10
- Build map-based and location-aware features targeting iOS 17+ with SwiftUI
11
- MapKit and modern CoreLocation async APIs. Use `Map` with `MapContentBuilder`
12
- for views, `CLLocationUpdate.liveUpdates()` for streaming location, and
13
- `CLMonitor` for geofencing.
10
+ Two frameworks do the work here. MapKit draws the map and answers questions
11
+ about places (search, geocoding, routes). CoreLocation tells you where the
12
+ device is and when it crosses a boundary. Since iOS 17 both have a Swift-first
13
+ surface: a SwiftUI `Map` whose content is written in a `MapContentBuilder`
14
+ closure, the async sequence `CLLocationUpdate.liveUpdates()` for position, and
15
+ the `CLMonitor` actor for geofences. Write new code against those; reach for
16
+ `MKMapView` or `CLLocationManager` only for the gaps named below.
14
17
 
15
- Read [references/mapkit-patterns.md](references/mapkit-patterns.md) when you need full map setup, search,
16
- routes, Look Around, snapshots, or iOS 26 place APIs. Read
17
- [references/mapkit-corelocation-patterns.md](references/mapkit-corelocation-patterns.md) when the task involves
18
- location update lifecycle, geofencing, background location, testing, or privacy keys.
18
+ Baseline: iOS 17. Sections that need a later release say so, and code that
19
+ needs it carries `@available`.
19
20
 
20
- ## Contents
21
+ Longer material lives in two references:
21
22
 
22
- - [Workflow](#workflow)
23
- - [SwiftUI Map View (iOS 17+)](#swiftui-map-view-ios-17)
24
- - [CoreLocation Modern API](#corelocation-modern-api)
25
- - [Geocoding](#geocoding)
26
- - [Search](#search)
27
- - [Directions](#directions)
28
- - [PlaceDescriptor (iOS 26+)](#placedescriptor-ios-26)
29
- - [Common Mistakes](#common-mistakes)
30
- - [Review Checklist](#review-checklist)
31
- - [References](#references)
23
+ - [Map patterns](references/mapkit-patterns.md): a complete
24
+ map screen, custom annotations, camera control, search with autocomplete,
25
+ routes, Look Around, snapshots, dense annotations, iOS 26 place APIs,
26
+ coordinate helpers, accessibility.
27
+ - [Location patterns](references/mapkit-corelocation-patterns.md):
28
+ the location update lifecycle, diagnostics, `CLServiceSession`, `CLMonitor`
29
+ geofencing, background location, legacy `CLLocationManager` cases, accuracy,
30
+ simulator testing, Info.plist privacy keys.
32
31
 
33
- ## Workflow
32
+ ## Scope
34
33
 
35
- ### 1. Add a map with markers or annotations
34
+ In scope: maps, markers and annotations, overlays, routes, search and
35
+ geocoding, the user's position, `CLMonitor` geofencing and the rules for
36
+ location in the background.
36
37
 
37
- 1. Import `MapKit`.
38
- 2. Create a `Map` view with optional `MapCameraPosition` binding.
39
- 3. Add `Marker`, `Annotation`, `MapPolyline`, `MapPolygon`, or `MapCircle`
40
- inside the `MapContentBuilder` closure.
41
- 4. Configure map style with `.mapStyle()`.
42
- 5. Add map controls with `.mapControls { }`.
43
- 6. Handle selection with a `selection:` binding.
38
+ Neighbouring work belongs elsewhere. MapKit does not draw CarPlay templates,
39
+ launch App Clips or pair Bluetooth hardware, so never claim it does. What this
40
+ skill owns is the handoff point: a geofence event, a search result or a route
41
+ that the other framework then acts on.
44
42
 
45
- ### 2. Track user location
43
+ | Topic | Where it goes |
44
+ |-------|---------------|
45
+ | CarPlay map templates, navigation alerts, CarPlay UI | CarPlay framework guidance (no skill in this collection) |
46
+ | App Clip invocation from a place card, size limits, handoff to the full app | `app-clips` |
47
+ | Pairing a beacon or accessory when a geofence fires | `core-bluetooth`, or AccessorySetupKit |
48
+ | A Live Activity used to keep background location alive | `live-activities` |
46
49
 
47
- 1. Add `NSLocationWhenInUseUsageDescription` to Info.plist.
48
- 2. On iOS 18+, create a `CLServiceSession` to manage authorization.
49
- 3. Iterate `CLLocationUpdate.liveUpdates()` in a `Task`.
50
- 4. Filter updates by distance or accuracy before updating the UI.
51
- 5. Stop the task when location tracking is no longer needed.
50
+ ## Workflows
52
51
 
53
- ### 3. Search for places
52
+ ### 1. Put places on a map
54
53
 
55
- 1. Configure `MKLocalSearchCompleter` for autocomplete suggestions.
56
- 2. Debounce user input (at least 300ms) before setting the query.
57
- 3. Convert selected completion to `MKLocalSearch.Request` for full results.
58
- 4. Display results as markers or in a list.
54
+ 1. `import MapKit` (and `SwiftUI`).
55
+ 2. Create a `Map`. Bind a `MapCameraPosition` if code needs to move the camera.
56
+ 3. Inside the content closure add `Marker`, `Annotation`, `MapPolyline`,
57
+ `MapPolygon` or `MapCircle`.
58
+ 4. Pick a look with `.mapStyle(...)`.
59
+ 5. Add controls with `.mapControls { ... }`.
60
+ 6. For tap-to-select, pass a `selection:` binding.
59
61
 
60
- ### 4. Get directions and display a route
62
+ ### 2. Follow the user's position
61
63
 
62
- 1. Create an `MKDirections.Request` with source and destination `MKMapItem`.
63
- 2. Set `transportType` (`.automobile`, `.walking`, `.transit`, `.cycling`).
64
- 3. Await `MKDirections.calculate()`.
65
- 4. Draw the route with `MapPolyline(route.polyline)`.
64
+ 1. Put a `NSLocationWhenInUseUsageDescription` string in Info.plist.
65
+ 2. On iOS 18 and later, create a `CLServiceSession` when the feature starts
66
+ and keep it until the feature ends; it drives the authorization prompt.
67
+ 3. Iterate `CLLocationUpdate.liveUpdates()` inside a `Task` that you keep.
68
+ 4. Drop samples that are inaccurate, old or implausible before the UI sees them.
69
+ 5. Cancel the task as soon as the feature no longer needs position.
66
70
 
67
- ### 5. Review existing map/location code
71
+ ### 3. Find places
68
72
 
69
- Run through the Review Checklist at the end of this file.
73
+ 1. Feed typed text to an `MKLocalSearchCompleter` for suggestions.
74
+ 2. Wait at least 300 ms after the last keystroke before updating the query.
75
+ 3. Turn the picked suggestion into an `MKLocalSearch.Request` for full results.
76
+ 4. Show the `MKMapItem` results as markers, a list, or both.
70
77
 
71
- ## SwiftUI Map View (iOS 17+)
78
+ ### 4. Route between two places
79
+
80
+ 1. Build an `MKDirections.Request` with a source and destination `MKMapItem`.
81
+ 2. Choose a mode in `transportType` (car, walking, transit or cycling).
82
+ 3. `try await MKDirections(request:).calculate()`.
83
+ 4. Draw `MapPolyline(route.polyline)`.
84
+
85
+ ### 5. Review existing code
86
+
87
+ Go through the [Review Checklist](#review-checklist) below.
88
+
89
+ ## SwiftUI Map (iOS 17+)
90
+
91
+ A SwiftUI map file imports both `SwiftUI` and `MapKit`.
72
92
 
73
93
  ```swift
74
- import MapKit
75
94
  import SwiftUI
95
+ import MapKit
76
96
 
77
- struct PlaceMap: View {
78
- @State private var position: MapCameraPosition = .automatic
97
+ struct TrailheadMap: View {
98
+ @State private var camera: MapCameraPosition = .automatic
99
+
100
+ private let lot = CLLocationCoordinate2D(latitude: 46.852, longitude: -121.760)
101
+ private let summit = CLLocationCoordinate2D(latitude: 46.853, longitude: -121.727)
79
102
 
80
103
  var body: some View {
81
- Map(position: $position) {
82
- Marker("Apple Park", coordinate: applePark)
83
- Marker("Infinite Loop", systemImage: "building.2",
84
- coordinate: infiniteLoop)
104
+ Map(position: $camera) {
105
+ Marker("Parking", coordinate: lot)
106
+ Marker("Summit", systemImage: "mountain.2.fill", coordinate: summit)
85
107
  }
86
108
  .mapStyle(.standard(elevation: .realistic))
87
109
  .mapControls {
@@ -93,173 +115,175 @@ struct PlaceMap: View {
93
115
  }
94
116
  ```
95
117
 
96
- ### Marker and Annotation
118
+ ### Marker or Annotation
97
119
 
98
- ```swift
99
- // Balloon marker -- simplest way to pin a location
100
- Marker("Cafe", systemImage: "cup.and.saucer.fill", coordinate: cafeCoord)
101
- .tint(.brown)
120
+ - `Marker(_:systemImage:coordinate:)` draws the system balloon. It is the
121
+ cheapest way to flag a spot, VoiceOver reads its title, and `.tint(_:)`
122
+ recolours it.
123
+ - `Annotation(_:coordinate:anchor:content:)` puts any SwiftUI view at a
124
+ coordinate. `anchor` is a `UnitPoint`; `.bottom` makes the bottom edge of
125
+ the view touch the coordinate, which suits pin-shaped content.
102
126
 
103
- // Annotation -- custom SwiftUI view at a coordinate
104
- Annotation("You", coordinate: userCoord, anchor: .bottom) {
105
- Image(systemName: "figure.wave")
127
+ ```swift
128
+ Annotation("Ranger station", coordinate: station, anchor: .bottom) {
129
+ Image(systemName: "house.fill")
106
130
  .padding(6)
107
- .background(.blue.gradient, in: .circle)
108
131
  .foregroundStyle(.white)
132
+ .background(Circle().fill(.green.gradient))
109
133
  }
110
134
  ```
111
135
 
112
- ### Overlays: Polyline, Polygon, Circle
136
+ ### Overlays
113
137
 
114
- ```swift
115
- Map {
116
- // Polyline from coordinates
117
- MapPolyline(coordinates: routeCoords)
118
- .stroke(.blue, lineWidth: 4)
119
-
120
- // Polygon (area highlight)
121
- MapPolygon(coordinates: parkBoundary)
122
- .foregroundStyle(.green.opacity(0.3))
123
- .stroke(.green, lineWidth: 2)
124
-
125
- // Circle (radius around a point)
126
- MapCircle(center: storeCoord, radius: 500)
127
- .foregroundStyle(.red.opacity(0.15))
128
- .stroke(.red, lineWidth: 1)
129
- }
130
- ```
138
+ | Content | Draws | Styling |
139
+ |---------|-------|---------|
140
+ | `MapPolyline(coordinates:)` | a line through the points | `.stroke(.orange, lineWidth: 4)` |
141
+ | `MapPolygon(coordinates:)` | a filled area | `.foregroundStyle(.teal.opacity(0.25))` plus `.stroke(...)` for the edge |
142
+ | `MapCircle(center:radius:)` | a circle, radius in metres | `.foregroundStyle(...)` and `.stroke(...)` |
131
143
 
132
- ### Camera Position
144
+ ### Camera position
133
145
 
134
- `MapCameraPosition` controls what the map displays. Bind it to let the user
135
- interact and to programmatically move the camera. Initialize it with `.region`,
136
- `.userLocation(fallback:)`, `.camera`, `.item`, `.rect`, or `.automatic`. See
137
- [references/mapkit-patterns.md](references/mapkit-patterns.md) ("Camera Control") for the position
138
- initializers, animated fly-to, framing content, and reading the visible region.
146
+ `MapCameraPosition` is what the map is showing. Bound to the map, it moves
147
+ when the user pans and moves the map when code assigns it. Its constructors:
148
+ `.region`, `.userLocation(fallback:)`, `.camera`, `.item`, `.rect`,
149
+ `.automatic`. Animated moves, framing all content and reading the visible
150
+ region are in [Camera Control](references/mapkit-patterns.md#camera-control).
139
151
 
140
- ### Map Style
152
+ ### Map styles
141
153
 
142
- ```swift
143
- .mapStyle(.standard) // Default road map
144
- .mapStyle(.standard(elevation: .realistic, showsTraffic: true))
145
- .mapStyle(.imagery) // Satellite
146
- .mapStyle(.imagery(elevation: .realistic)) // 3D satellite
147
- .mapStyle(.hybrid) // Satellite + labels
148
- .mapStyle(.hybrid(elevation: .realistic, showsTraffic: true))
149
- ```
154
+ | Modifier | Result |
155
+ |----------|--------|
156
+ | `.mapStyle(.standard)` | default road map |
157
+ | `.mapStyle(.standard(elevation: .realistic, showsTraffic: true))` | roads, 3D terrain, live traffic |
158
+ | `.mapStyle(.imagery)` | satellite |
159
+ | `.mapStyle(.imagery(elevation: .realistic))` | satellite in 3D |
160
+ | `.mapStyle(.hybrid)` | satellite with labels |
161
+ | `.mapStyle(.hybrid(elevation: .realistic, showsTraffic: true))` | labelled satellite, 3D terrain, live traffic |
150
162
 
151
- ### Map Interaction Modes
163
+ ### Interaction modes
152
164
 
153
- ```swift
154
- .mapInteractionModes(.all) // Default: pan, zoom, rotate, pitch
155
- .mapInteractionModes(.pan) // Pan only
156
- .mapInteractionModes([.pan, .zoom]) // Pan and zoom
157
- .mapInteractionModes([]) // Static map (no interaction)
158
- ```
165
+ | Modifier | Allows |
166
+ |----------|--------|
167
+ | `.mapInteractionModes(.all)` | pan, zoom, rotate, pitch (the default) |
168
+ | `.mapInteractionModes(.pan)` | panning only |
169
+ | `.mapInteractionModes([.pan, .zoom])` | moving and zooming, no rotation or tilt |
170
+ | `.mapInteractionModes([])` | nothing; a static picture |
171
+
172
+ ### Selection
159
173
 
160
- ### Map Selection
174
+ The value in `.tag(_:)` must have the same type as the `selection` binding,
175
+ or taps select nothing.
161
176
 
162
177
  ```swift
163
- @State private var selectedMarker: MKMapItem?
178
+ struct CampsiteMap: View {
179
+ let sites: [Campsite]
180
+ @State private var chosen: MKMapItem?
181
+ @State private var headline = ""
164
182
 
165
- Map(selection: $selectedMarker) {
166
- ForEach(places) { place in
167
- Marker(place.name, coordinate: place.coordinate)
168
- .tag(place.mapItem) // Tag must match selection type
183
+ var body: some View {
184
+ Map(selection: $chosen) {
185
+ ForEach(sites) { site in
186
+ Marker(site.name, coordinate: site.coordinate)
187
+ .tag(site.mapItem)
188
+ }
189
+ }
190
+ .onChange(of: chosen) { _, item in
191
+ guard let item else { return }
192
+ headline = item.name ?? ""
193
+ }
169
194
  }
170
195
  }
171
- .onChange(of: selectedMarker) { _, newValue in
172
- guard let item = newValue else { return }
173
- // React to selection
174
- }
175
196
  ```
176
197
 
177
- ## CoreLocation Modern API
198
+ ## CoreLocation
178
199
 
179
200
  ### CLLocationUpdate.liveUpdates() (iOS 17+)
180
201
 
181
- Replace `CLLocationManagerDelegate` callbacks with a single async sequence.
182
- Each iteration yields a `CLLocationUpdate` containing an optional `CLLocation`.
183
- On iOS 18+, handle diagnostic states such as denied authorization, globally
184
- disabled Location Services, unavailable location, and insufficient in-use
185
- conditions with a visible degraded path instead of silently waiting forever.
186
- Store the task so the feature can cancel it, and reject invalid, inaccurate,
187
- stale, or unusable movement data before driving map UI or background work.
202
+ One async sequence replaces the `CLLocationManagerDelegate` callbacks. Each
203
+ element is a `CLLocationUpdate` whose `location` is optional. Rules:
204
+
205
+ - Store the iterating `Task` in a property; cancelling it is how tracking stops.
206
+ - Throw away samples with invalid or poor accuracy, old timestamps or
207
+ impossible jumps before they touch map UI or background work.
208
+ - On iOS 18 and later the update also carries diagnostics (authorization
209
+ denied, Location Services off system-wide, location unavailable, app not
210
+ sufficiently in use). React with a visible fallback instead of waiting on a
211
+ sequence that will not deliver.
188
212
 
189
213
  ```swift
190
214
  import CoreLocation
215
+ import Observation
191
216
 
192
217
  @MainActor
193
218
  @Observable
194
- final class LocationTracker {
195
- var currentLocation: CLLocation?
196
- private var updateTask: Task<Void, Never>?
219
+ final class RunTracker {
220
+ private(set) var lastFix: CLLocation?
221
+ private var stream: Task<Void, Never>?
197
222
 
198
- func startTracking() {
199
- updateTask = Task {
223
+ func begin() {
224
+ stream?.cancel()
225
+ stream = Task {
200
226
  do {
201
- let updates = CLLocationUpdate.liveUpdates()
202
- for try await update in updates {
203
- guard let location = update.location else { continue }
204
- // Filter by horizontal accuracy
205
- guard location.horizontalAccuracy >= 0,
206
- location.horizontalAccuracy < 50 else { continue }
207
- currentLocation = location
227
+ for try await reading in CLLocationUpdate.liveUpdates() {
228
+ guard let fix = reading.location,
229
+ fix.horizontalAccuracy >= 0,
230
+ fix.horizontalAccuracy < 50 else { continue }
231
+ lastFix = fix
208
232
  }
209
233
  } catch is CancellationError {
210
- // Expected when tracking stops.
211
234
  } catch {
212
- currentLocation = nil
235
+ lastFix = nil
213
236
  }
214
237
  }
215
238
  }
216
239
 
217
- func stopTracking() {
218
- updateTask?.cancel()
219
- updateTask = nil
240
+ func end() {
241
+ stream?.cancel()
242
+ stream = nil
220
243
  }
221
244
  }
222
245
  ```
223
246
 
247
+ Diagnostics, the full filter set and a mapping from each state to UI are in
248
+ the [location reference](references/mapkit-corelocation-patterns.md#diagnostics-and-fallbacks-ios-18).
249
+
224
250
  ### CLServiceSession (iOS 18+)
225
251
 
226
- Declare authorization requirements for a feature's lifetime. Hold a reference
227
- to the session for as long as you need location services.
252
+ A `CLServiceSession` states what authorization a feature needs, for as long
253
+ as the feature runs. Store it in a property and release it when the feature
254
+ ends. On iOS 18 `liveUpdates()` and `CLMonitor` create a session implicitly
255
+ when you have not; create one yourself when you need `.always` or full
256
+ accuracy. It is not available on macOS.
228
257
 
229
258
  ```swift
230
- // When-in-use authorization with full accuracy preference
231
- let session = CLServiceSession(
259
+ @available(iOS 18, *)
260
+ let nearbySession = CLServiceSession(
232
261
  authorization: .whenInUse,
233
- fullAccuracyPurposeKey: "NearbySearchPurpose"
262
+ fullAccuracyPurposeKey: "NearbyTrails"
234
263
  )
235
- // Hold `session` as a stored property; release it when done.
236
264
  ```
237
265
 
238
- On iOS 18+, `CLLocationUpdate.liveUpdates()` and `CLMonitor` take an implicit
239
- `CLServiceSession` if you do not create one explicitly. Create one explicitly
240
- when you need `.always` authorization or full accuracy.
266
+ ### Authorization
241
267
 
242
- ### Authorization Flow
268
+ - `NSLocationWhenInUseUsageDescription` is required for any location use.
269
+ - `NSLocationAlwaysAndWhenInUseUsageDescription` only when the feature truly
270
+ needs `.always`.
243
271
 
244
- ```swift
245
- // Info.plist keys (required):
246
- // NSLocationWhenInUseUsageDescription
247
- // NSLocationAlwaysAndWhenInUseUsageDescription (only if .always needed)
272
+ A denied user should see why the feature is empty and a way out:
248
273
 
249
- // Check authorization and guide user to Settings when denied
250
- struct LocationPermissionView: View {
274
+ ```swift
275
+ struct LocationOffView: View {
251
276
  @Environment(\.openURL) private var openURL
252
277
 
253
278
  var body: some View {
254
279
  ContentUnavailableView {
255
- Label("Location Access Denied", systemImage: "location.slash")
280
+ Label("Location is off", systemImage: "location.slash")
256
281
  } description: {
257
- Text("Enable location access in Settings to use this feature.")
282
+ Text("Allow location access to see trails near you.")
258
283
  } actions: {
259
284
  Button("Open Settings") {
260
- if let url = URL(string: UIApplication.openSettingsURLString) {
261
- openURL(url)
262
- }
285
+ guard let settings = URL(string: UIApplication.openSettingsURLString) else { return }
286
+ openURL(settings)
263
287
  }
264
288
  }
265
289
  }
@@ -268,164 +292,168 @@ struct LocationPermissionView: View {
268
292
 
269
293
  ## Geocoding
270
294
 
271
- ### CLGeocoder (iOS 8+)
295
+ ### MKGeocodingRequest and MKReverseGeocodingRequest (iOS 26+)
296
+
297
+ MapKit now geocodes by itself and returns `MKMapItem`, which carries more than
298
+ a placemark: an `MKAddress` and `MKAddressRepresentations` for formatting.
299
+ Both initializers are failable; `mapItems` is an async throwing property.
272
300
 
273
301
  ```swift
274
- let geocoder = CLGeocoder()
302
+ @available(iOS 26, *)
303
+ func lookUp(_ text: String) async throws -> MKMapItem? {
304
+ guard let request = MKGeocodingRequest(addressString: text) else { return nil }
305
+ return try await request.mapItems.first
306
+ }
307
+ ```
308
+
309
+ Reverse lookup is `MKReverseGeocodingRequest(location:)`. Formatting and
310
+ batch lookups are in [Geocoding and Places on iOS 26](references/mapkit-patterns.md#geocoding-and-places-on-ios-26).
311
+
312
+ ### CLGeocoder (iOS 5 to iOS 25, deprecated in iOS 26)
275
313
 
276
- // Forward geocoding: address string -> coordinates
277
- let placemarks = try await geocoder.geocodeAddressString("1 Apple Park Way, Cupertino")
278
- if let location = placemarks.first?.location {
279
- print(location.coordinate) // CLLocationCoordinate2D
314
+ Use it only while the deployment target is below iOS 26. Every `CLPlacemark`
315
+ field is optional. `CLGeocoder` is not `Sendable`, so Swift 6 rejects one
316
+ shared global instance; make a geocoder for each lookup instead.
317
+
318
+ ```swift
319
+ func coordinate(for address: String) async throws -> CLLocationCoordinate2D? {
320
+ try await CLGeocoder().geocodeAddressString(address).first?.location?.coordinate
280
321
  }
281
322
 
282
- // Reverse geocoding: coordinates -> placemark
283
- let location = CLLocation(latitude: 37.3349, longitude: -122.0090)
284
- let placemarks = try await geocoder.reverseGeocodeLocation(location)
285
- if let placemark = placemarks.first {
286
- let address = [placemark.name, placemark.locality, placemark.administrativeArea]
323
+ func label(for spot: CLLocation) async throws -> String {
324
+ let marks = try await CLGeocoder().reverseGeocodeLocation(spot)
325
+ guard let mark = marks.first else { return "" }
326
+ return [mark.name, mark.locality, mark.administrativeArea]
287
327
  .compactMap { $0 }
288
328
  .joined(separator: ", ")
289
329
  }
290
330
  ```
291
331
 
292
- ### MKGeocodingRequest and MKReverseGeocodingRequest (iOS 26+)
293
-
294
- New MapKit-native geocoding returns `MKMapItem` with richer data and `MKAddress`
295
- / `MKAddressRepresentations` for flexible address formatting. Construct
296
- `MKGeocodingRequest(addressString:)` or `MKReverseGeocodingRequest(location:)` and
297
- await `.mapItems`. See [references/mapkit-patterns.md](references/mapkit-patterns.md) ("iOS 26 New
298
- APIs") for both, plus `MKAddressRepresentations` formatting.
299
-
300
332
  ## Search
301
333
 
302
- ### MKLocalSearchCompleter (Autocomplete)
303
-
304
- Set `queryFragment` on an `MKLocalSearchCompleter` and read `results` from its
305
- delegate for suggestions. Debounce input (300ms+) and constrain `completer.region`
306
- to the visible map region.
334
+ ### MKLocalSearchCompleter (autocomplete)
307
335
 
308
- ### MKLocalSearch (Full Search)
336
+ Set `queryFragment` and read `results` from the delegate. Debounce input by
337
+ 300 ms or more and set `completer.region` to the visible map region so
338
+ suggestions stay local.
309
339
 
310
- Convert a selected completion (or a natural-language query) into full `MKMapItem`
311
- results:
340
+ ### MKLocalSearch (full results)
312
341
 
313
342
  ```swift
314
- func search(for completion: MKLocalSearchCompletion) async throws -> [MKMapItem] {
315
- let request = MKLocalSearch.Request(completion: completion)
343
+ func places(for pick: MKLocalSearchCompletion) async throws -> [MKMapItem] {
344
+ let request = MKLocalSearch.Request(completion: pick)
316
345
  request.resultTypes = [.pointOfInterest, .address]
317
- let response = try await MKLocalSearch(request: request).start()
318
- return response.mapItems
346
+ let reply = try await MKLocalSearch(request: request).start()
347
+ return reply.mapItems
319
348
  }
320
349
  ```
321
350
 
322
- For a natural-language query, set `request.naturalLanguageQuery` and
323
- `request.region` instead. See [references/mapkit-patterns.md](references/mapkit-patterns.md) ("Search
324
- with Autocomplete") for the full completer delegate class and a `.searchable`
325
- view integration.
351
+ For free text, set `request.naturalLanguageQuery` and `request.region`
352
+ instead of passing a completion. The delegate-based service and the
353
+ `.searchable` screen are in
354
+ [Autocomplete Search](references/mapkit-patterns.md#autocomplete-search).
326
355
 
327
356
  ## Directions
328
357
 
358
+ `MKMapItem` and `MKRoute` are not `Sendable`. Keep the helper on the main
359
+ actor, where the SwiftUI view that calls it already runs, so the items never
360
+ cross an isolation boundary:
361
+
329
362
  ```swift
330
- func getDirections(from source: MKMapItem, to destination: MKMapItem,
331
- transport: MKDirectionsTransportType = .automobile) async throws -> MKRoute? {
363
+ @MainActor
364
+ func fastestRoute(
365
+ from start: MKMapItem,
366
+ to end: MKMapItem,
367
+ by mode: MKDirectionsTransportType = .automobile
368
+ ) async throws -> MKRoute? {
332
369
  let request = MKDirections.Request()
333
- request.source = source
334
- request.destination = destination
335
- request.transportType = transport
336
- let directions = MKDirections(request: request)
337
- let response = try await directions.calculate()
338
- return response.routes.first
370
+ request.source = start
371
+ request.destination = end
372
+ request.transportType = mode
373
+ let reply = try await MKDirections(request: request).calculate()
374
+ return reply.routes.first
339
375
  }
340
376
  ```
341
377
 
342
- ### Display Route on Map
378
+ ### Drawing the route
343
379
 
344
380
  ```swift
345
- @State private var route: MKRoute?
381
+ struct FerryRouteMap: View {
382
+ let pier: MKMapItem
383
+ let island: MKMapItem
384
+ @State private var route: MKRoute?
346
385
 
347
- Map {
348
- if let route {
349
- MapPolyline(route.polyline)
350
- .stroke(.blue, lineWidth: 5)
386
+ var body: some View {
387
+ Map {
388
+ if let route {
389
+ MapPolyline(route.polyline).stroke(.teal, lineWidth: 5)
390
+ }
391
+ Marker(item: pier)
392
+ Marker(item: island)
393
+ }
394
+ .task { route = try? await fastestRoute(from: pier, to: island) }
351
395
  }
352
- Marker("Start", coordinate: startCoord)
353
- Marker("End", coordinate: endCoord)
354
- }
355
- .task {
356
- route = try? await getDirections(from: startItem, to: endItem)
357
396
  }
358
397
  ```
359
398
 
360
- ### ETA and Cycling Directions
399
+ ### Travel time only, and cycling
361
400
 
362
- For travel time only, use `MKDirections.calculateETA()` (returns
363
- `expectedTravelTime` without route geometry). For bike routes, set
364
- `request.transportType = .cycling` (iOS 14+). See
365
- [references/mapkit-patterns.md](references/mapkit-patterns.md) ("ETA Calculation" and "Cycling
366
- Directions") for both.
401
+ - `MKDirections.calculateETA()` returns `expectedTravelTime` without route
402
+ geometry; use it when a label is all you need
403
+ ([ETA Calculation](references/mapkit-patterns.md#eta-calculation)).
404
+ - Bike routes: `request.transportType = .cycling`, iOS 14 and later
405
+ ([Cycling Directions](references/mapkit-patterns.md#cycling-directions-ios-14)).
367
406
 
368
407
  ## PlaceDescriptor (iOS 26+)
369
408
 
370
- Create rich place references from coordinates or addresses without needing a
371
- Place ID. Requires `import GeoToolbox`.
409
+ `PlaceDescriptor`, from `GeoToolbox`, describes a place by coordinate or
410
+ address when you have no MapKit place ID. `MKMapItemRequest` resolves it into
411
+ a full `MKMapItem`.
372
412
 
373
413
  ```swift
374
414
  import GeoToolbox
415
+ import MapKit
375
416
 
376
417
  @available(iOS 26, *)
377
- func lookupPlace(name: String, coordinate: CLLocationCoordinate2D) async throws -> MKMapItem {
378
- let descriptor = PlaceDescriptor(
379
- representations: [.coordinate(coordinate)],
380
- commonName: name
381
- )
382
- let request = MKMapItemRequest(placeDescriptor: descriptor)
383
- return try await request.mapItem
418
+ func mapItem(near point: CLLocationCoordinate2D, named name: String) async throws -> MKMapItem {
419
+ let place = PlaceDescriptor(representations: [.coordinate(point)], commonName: name)
420
+ return try await MKMapItemRequest(placeDescriptor: place).mapItem
384
421
  }
385
422
  ```
386
423
 
387
424
  ## Common Mistakes
388
425
 
389
- **DON'T:** Request always authorization upfront.
390
- **DO:** Start with when-in-use authorization. On iOS 18+, hold a `CLServiceSession`
391
- for the feature lifetime; request `.always` only for background features that
392
- need system relaunch after termination.
393
-
394
- **DON'T:** Use `CLLocationManagerDelegate` for simple location fetches on iOS 17+.
395
- **DO:** Use `CLLocationUpdate.liveUpdates()` async stream for cleaner, more concise code.
396
-
397
- **DON'T:** Ignore `CLLocationUpdate` diagnostics such as denied, globally denied, or unavailable location.
398
- **DO:** Stop or degrade the feature, show recovery UI such as Settings guidance, and keep search/manual flows usable.
399
-
400
- **DON'T:** Let `liveUpdates()` run from an unowned task after the map/view is gone.
401
- **DO:** Store the `Task`, cancel it when the feature stops, and filter invalid, inaccurate, stale, or impossible movement fixes.
402
-
403
- **DON'T:** Force-unwrap `CLPlacemark` properties - they are all optional.
404
- **DO:** Use nil-coalescing: `placemark.locality ?? "Unknown"`.
405
-
406
- **DON'T:** Fire `MKLocalSearchCompleter` queries on every keystroke.
407
- **DO:** Debounce with `.task(id: searchText)` + `Task.sleep(for: .milliseconds(300))`.
408
-
409
- **DON'T:** Silently fail when location authorization is denied.
410
- **DO:** Detect `.denied` status and show an alert with a Settings deep link.
411
-
412
- **DON'T:** Assume geocoding always succeeds - handle empty results and network errors.
426
+ | Mistake | Do instead |
427
+ |---------|-----------|
428
+ | Asking for Always authorization at launch | Start with when-in-use; ask for `.always` only for a background feature that needs relaunch after termination |
429
+ | No `CLServiceSession` on iOS 18+ | Hold one for the life of the feature |
430
+ | A `CLLocationManagerDelegate` just to read position on iOS 17+ | Iterate `liveUpdates()`; less code, same result |
431
+ | Ignoring diagnostics (denied, off system-wide, unavailable) | Switch to a reduced mode, point the user at Settings, and leave search and manual entry usable |
432
+ | `liveUpdates()` in a task nobody owns | Keep the `Task` in a property and cancel it with the screen; filter bad fixes |
433
+ | Force-unwrapping `CLPlacemark` fields | They are all optional: `mark.locality ?? "Unknown"` |
434
+ | Querying the completer on every keystroke | `.task(id: text)` plus `Task.sleep(for: .milliseconds(300))` |
435
+ | Silent failure when denied | Detect `.denied` and offer a Settings link |
436
+ | Assuming geocoding returns something | Plan for zero matches and for being offline |
413
437
 
414
438
  ## Review Checklist
415
439
 
416
- - [ ] Info.plist has `NSLocationWhenInUseUsageDescription` with specific reason
417
- - [ ] Authorization denial handled with Settings deep link
418
- - [ ] `CLLocationUpdate` task cancelled when not needed (battery)
419
- - [ ] Location accuracy appropriate for the use case
420
- - [ ] Map annotations use `Identifiable` data with stable IDs
421
- - [ ] Geocoding errors handled (network failure, no results)
422
- - [ ] Search completer input debounced
423
- - [ ] `CLMonitor` limited to 20 conditions, instance kept alive
440
+ - [ ] `NSLocationWhenInUseUsageDescription` is present and names a concrete benefit
441
+ - [ ] A denied user gets an explanation and a Settings deep link
442
+ - [ ] The `CLLocationUpdate` task is cancelled when not needed, to save battery
443
+ - [ ] Requested accuracy matches what the feature needs
444
+ - [ ] Annotation data is `Identifiable` with stable IDs
445
+ - [ ] Geocoding handles network failure and empty results
446
+ - [ ] Completer input is debounced
447
+ - [ ] `CLMonitor` stays at or under 20 conditions and the instance is kept alive
424
448
  - [ ] Background location uses `CLBackgroundActivitySession`
425
- - [ ] Map tested with VoiceOver
426
- - [ ] Map annotation view models and location UI updates are `@MainActor`-isolated
449
+ - [ ] The map has been tried with VoiceOver
450
+ - [ ] Annotation models and location-driven UI state are `@MainActor`
427
451
 
428
452
  ## References
429
453
 
430
- - [references/mapkit-patterns.md](references/mapkit-patterns.md) - Map setup, annotations, search, routes, clustering, Look Around, snapshots.
431
- - [references/mapkit-corelocation-patterns.md](references/mapkit-corelocation-patterns.md) - CLLocationUpdate, CLMonitor, CLServiceSession, background location, testing.
454
+ - [Map patterns](references/mapkit-patterns.md): map setup,
455
+ annotations, camera, search, routes, dense maps and clustering, Look Around,
456
+ snapshots, iOS 26 APIs.
457
+ - [Location patterns](references/mapkit-corelocation-patterns.md):
458
+ `CLLocationUpdate`, `CLServiceSession`, `CLMonitor`, background location,
459
+ testing, privacy keys.