@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,412 +1,257 @@
1
1
  ---
2
2
  name: weatherkit
3
- description: "Fetch current, hourly, and daily weather forecasts and display required attribution using WeatherKit. Use when integrating weather data, showing forecasts, handling weather alerts, displaying Apple Weather attribution, or querying historical weather statistics in iOS apps."
3
+ description: "WeatherKit on iOS: current, hourly, daily and minute forecasts, alerts, historical statistics, dataset selection, caching. Use when integrating weather data, showing forecasts, handling severe alerts or displaying the required Apple Weather attribution and legal link."
4
4
  metadata:
5
- source: "dpearson2699/swift-ios-skills (PolyForm Perimeter 1.0.0)"
5
+ source: multi-agent-pipeline
6
6
  ---
7
7
 
8
8
  # WeatherKit
9
9
 
10
- Fetch current conditions, hourly and daily forecasts, weather alerts, and
11
- historical statistics using `WeatherService`. Display required Apple Weather
12
- attribution. Targets Swift 6.3 / iOS 26+.
10
+ WeatherKit gives an app the same forecast data the system Weather app uses,
11
+ through one async service. The rules that matter most are legal and economic:
12
+ attribution is required wherever the data shows, and every dataset you request
13
+ counts against the app's quota. Code targets Swift 6.3 and iOS 26.
13
14
 
14
- ## Contents
15
-
16
- - [Setup](#setup)
17
- - [Fetching Current Weather](#fetching-current-weather)
18
- - [Forecasts](#forecasts)
19
- - [Weather Alerts](#weather-alerts)
20
- - [Selective Queries](#selective-queries)
21
- - [Attribution](#attribution)
22
- - [Availability](#availability)
23
- - [Common Mistakes](#common-mistakes)
24
- - [Review Checklist](#review-checklist)
25
- - [References](#references)
15
+ Dashboard, charts, historical statistics, condition mapping, caching and
16
+ location plumbing are in
17
+ [references/weatherkit-patterns.md](references/weatherkit-patterns.md).
26
18
 
27
19
  ## Setup
28
20
 
29
- ### Project Configuration
21
+ ### Project configuration
30
22
 
31
- 1. Enable the **WeatherKit** capability in Xcode (adds the entitlement)
32
- 2. Enable WeatherKit for your App ID in the Apple Developer portal
33
- 3. Add `NSLocationWhenInUseUsageDescription` to Info.plist if using device location
34
- 4. WeatherKit requires an active Apple Developer Program membership
23
+ 1. In Xcode, add the **WeatherKit** capability. This writes the entitlement.
24
+ 2. In the developer portal, enable WeatherKit for the same App ID (both the
25
+ capability and the service checkbox are needed).
26
+ 3. The account must be a paid, currently active developer program membership.
27
+ 4. If the app sends the device's own position, add
28
+ `NSLocationWhenInUseUsageDescription` and get location permission first.
35
29
 
36
- ### Import
30
+ ### Imports and the service
37
31
 
38
32
  ```swift
39
33
  import WeatherKit
40
34
  import CoreLocation
35
+
36
+ let forecaster = WeatherService.shared // or WeatherService()
41
37
  ```
42
38
 
43
- ### Creating the Service
39
+ `WeatherService` is `Sendable`, so one instance can be used from any task or
40
+ actor.
41
+
42
+ ## Fetching current weather
44
43
 
45
- Use the shared singleton or create an instance. The service is `Sendable` and
46
- thread-safe.
44
+ The plain call returns every dataset in a `Weather` value:
47
45
 
48
46
  ```swift
49
- let weatherService = WeatherService.shared
50
- // or
51
- let weatherService = WeatherService()
47
+ let site = CLLocation(latitude: 38.42, longitude: 27.14)
48
+ let report = try await forecaster.weather(for: site)
49
+ let now = report.currentWeather
52
50
  ```
53
51
 
54
- ## Fetching Current Weather
52
+ `CurrentWeather` fields you will use most:
55
53
 
56
- Fetch current conditions for a location. Returns a `Weather` object with all
57
- available datasets.
54
+ | Property | Type | Note |
55
+ | --- | --- | --- |
56
+ | `temperature` | `Measurement<UnitTemperature>` | Format with `.formatted()` |
57
+ | `condition` | `WeatherCondition` | Enum with a readable `description` |
58
+ | `symbolName` | `String` | An SF Symbol name |
59
+ | `humidity` | `Double` | Fraction from 0 to 1 |
60
+ | `wind` | `Wind` | `speed`, `direction`, `gust` |
61
+ | `uvIndex` | `UVIndex` | `value` and `category` |
58
62
 
59
63
  ```swift
60
- func fetchCurrentWeather(for location: CLLocation) async throws -> CurrentWeather {
61
- let weather = try await weatherService.weather(for: location)
62
- return weather.currentWeather
63
- }
64
-
65
- // Using the result
66
- func displayCurrent(_ current: CurrentWeather) {
67
- let temp = current.temperature // Measurement<UnitTemperature>
68
- let condition = current.condition // WeatherCondition enum
69
- let symbol = current.symbolName // SF Symbol name
70
- let humidity = current.humidity // Double (0-1)
71
- let wind = current.wind // Wind (speed, direction, gust)
72
- let uvIndex = current.uvIndex // UVIndex
73
-
74
- print("\(condition): \(temp.formatted())")
75
- }
64
+ headline = "\(now.temperature.formatted()), \(now.condition.description)"
76
65
  ```
77
66
 
78
67
  ## Forecasts
79
68
 
80
- ### Hourly Forecast
69
+ ### Hourly
81
70
 
82
- Returns 25 contiguous hours starting from the current hour by default.
71
+ At the time of writing, Apple's documentation says the default hourly forecast
72
+ covers 25 consecutive hours starting with the current hour; read the count from
73
+ the result rather than hard-coding it. `hourlyForecast` is a `Forecast<HourWeather>`:
83
74
 
84
75
  ```swift
85
- func fetchHourlyForecast(for location: CLLocation) async throws -> Forecast<HourWeather> {
86
- let weather = try await weatherService.weather(for: location)
87
- return weather.hourlyForecast
88
- }
89
-
90
- // Iterate hours
91
- for hour in hourlyForecast {
92
- print("\(hour.date): \(hour.temperature.formatted()), \(hour.condition)")
76
+ let timeline = report.hourlyForecast.map { slot in
77
+ (slot.date.formatted(.dateTime.hour()), slot.temperature.formatted(), slot.condition.description)
93
78
  }
94
79
  ```
95
80
 
96
- ### Daily Forecast
81
+ ### Daily
97
82
 
98
- Returns 10 contiguous days starting from the current day by default.
83
+ At the time of writing, Apple's documentation says the default daily forecast
84
+ covers 10 consecutive days starting today; again, read the count from the
85
+ result.
86
+ `dailyForecast` is a `Forecast<DayWeather>`:
99
87
 
100
88
  ```swift
101
- func fetchDailyForecast(for location: CLLocation) async throws -> Forecast<DayWeather> {
102
- let weather = try await weatherService.weather(for: location)
103
- return weather.dailyForecast
104
- }
105
-
106
- // Iterate days
107
- for day in dailyForecast {
108
- print("\(day.date): \(day.lowTemperature.formatted()) - \(day.highTemperature.formatted())")
109
- print(" Condition: \(day.condition), Precipitation: \(day.precipitationChance)")
89
+ for day in report.dailyForecast {
90
+ let range = "\(day.lowTemperature.formatted()) to \(day.highTemperature.formatted())"
91
+ let rain = day.precipitationChance.formatted(.percent)
92
+ rows.append("\(day.condition.description), \(range), rain \(rain)")
110
93
  }
111
94
  ```
112
95
 
113
- ### Custom Date Range
114
-
115
- Request forecasts for specific date ranges using `WeatherQuery`.
96
+ ### A custom range
116
97
 
117
98
  ```swift
118
- func fetchExtendedForecast(for location: CLLocation) async throws -> Forecast<DayWeather> {
119
- let startDate = Date.now
120
- let endDate = Calendar.current.date(byAdding: .day, value: 10, to: startDate)!
121
-
122
- let forecast = try await weatherService.weather(
123
- for: location,
124
- including: .daily(startDate: startDate, endDate: endDate)
99
+ func nextWeek(at site: CLLocation) async throws -> Forecast<DayWeather>? {
100
+ let weekStart = Date.now
101
+ guard let weekEnd = Calendar.current.date(byAdding: DateComponents(day: 7), to: weekStart) else { return nil }
102
+ let service = WeatherService.shared
103
+ return try await service.weather(
104
+ for: site,
105
+ including: .daily(startDate: weekStart, endDate: weekEnd)
125
106
  )
126
- return forecast
127
107
  }
128
108
  ```
129
109
 
130
- ## Weather Alerts
110
+ `.hourly(startDate:endDate:)` works the same way for hours.
131
111
 
132
- Fetch active weather alerts for a location. Alerts include severity, summary,
133
- and affected regions.
112
+ ## Weather alerts
134
113
 
135
- ```swift
136
- func fetchAlerts(for location: CLLocation) async throws -> [WeatherAlert]? {
137
- let weather = try await weatherService.weather(for: location)
138
- return weather.weatherAlerts
139
- }
114
+ `weatherAlerts` is `[WeatherAlert]?`; it is `nil` where alerts are not
115
+ provided.
140
116
 
141
- // Process alerts
142
- if let alerts = weatherAlerts {
117
+ ```swift
118
+ if let alerts = report.weatherAlerts {
143
119
  for alert in alerts {
144
- print("Alert: \(alert.summary)")
145
- print("Severity: \(alert.severity)")
146
- print("Region: \(alert.region)")
147
- if let detailsURL = alert.detailsURL {
148
- // Link to full alert details
149
- }
120
+ // alert.summary: String, alert.severity: WeatherSeverity,
121
+ // alert.region: String?, alert.detailsURL: URL, alert.source: String
122
+ banners.append(alert.summary)
150
123
  }
151
124
  }
152
125
  ```
153
126
 
154
- ## Selective Queries
155
-
156
- Fetch only the datasets you need to minimize API usage and response size. Each
157
- `WeatherQuery` type maps to one dataset.
158
-
159
- ### Single Dataset
127
+ `detailsURL` is not optional; link to it so users can read the full notice
128
+ from the issuing agency.
160
129
 
161
- ```swift
162
- let current = try await weatherService.weather(
163
- for: location,
164
- including: .current
165
- )
166
- // current is CurrentWeather
167
- ```
130
+ ## Selective queries
168
131
 
169
- ### Multiple Datasets
132
+ Ask only for what the screen shows. Each `WeatherQuery` maps to one dataset,
133
+ and each dataset is a request against the quota and more bytes over the wire.
170
134
 
171
135
  ```swift
172
- let (current, hourly, daily) = try await weatherService.weather(
173
- for: location,
174
- including: .current, .hourly, .daily
175
- )
176
- // current: CurrentWeather, hourly: Forecast<HourWeather>, daily: Forecast<DayWeather>
177
- ```
136
+ // One dataset: the return type is the dataset itself.
137
+ let nowOnly: CurrentWeather = try await forecaster.weather(for: site, including: .current)
178
138
 
179
- ### Minute Forecast
139
+ // Several datasets: the results come back as a tuple, in the order requested.
140
+ let (now, hours, days) = try await forecaster.weather(for: site, including: .current, .hourly, .daily)
180
141
 
181
- Available in limited regions. Returns precipitation forecasts at minute
182
- granularity for the next hour.
183
-
184
- ```swift
185
- let minuteForecast = try await weatherService.weather(
186
- for: location,
187
- including: .minute
188
- )
189
- // minuteForecast: Forecast<MinuteWeather>? (nil if unavailable)
142
+ // Next-hour precipitation, minute by minute. Only some regions have it.
143
+ if let nextHour = try await forecaster.weather(for: site, including: .minute) {
144
+ rainStartsSoon = nextHour.contains { $0.precipitationChance > 0.5 }
145
+ }
190
146
  ```
191
147
 
192
- ### Available Query Types
193
-
194
- | Query | Return Type | Description |
195
- |---|---|---|
196
- | `.current` | `CurrentWeather` | Current observed conditions |
197
- | `.hourly` | `Forecast<HourWeather>` | 25 hours from current hour |
198
- | `.daily` | `Forecast<DayWeather>` | 10 days from today |
199
- | `.minute` | `Forecast<MinuteWeather>?` | Next-hour precipitation (limited regions) |
200
- | `.alerts` | `[WeatherAlert]?` | Active weather alerts |
201
- | `.availability` | `WeatherAvailability` | Dataset availability for location |
148
+ | Query | Result type | Notes |
149
+ | --- | --- | --- |
150
+ | `.current` | `CurrentWeather` | |
151
+ | `.hourly` | `Forecast<HourWeather>` | Default span per Apple's docs: 25 hours from now |
152
+ | `.daily` | `Forecast<DayWeather>` | Default span per Apple's docs: 10 days from today |
153
+ | `.minute` | `Forecast<MinuteWeather>?` | `nil` where unsupported |
154
+ | `.alerts` | `[WeatherAlert]?` | `nil` where unsupported |
155
+ | `.availability` | `WeatherAvailability` | Which region-limited datasets exist here |
202
156
 
203
157
  ## Attribution
204
158
 
205
- Apple requires apps using WeatherKit to display attribution. This is a
206
- legal requirement.
207
-
208
- ### Fetching Attribution
159
+ Showing Apple Weather attribution is a legal requirement of using WeatherKit,
160
+ not a design choice. Fetch it from the service:
209
161
 
210
162
  ```swift
211
- func fetchAttribution() async throws -> WeatherAttribution {
212
- return try await weatherService.attribution
213
- }
163
+ let credit = try await forecaster.attribution
214
164
  ```
215
165
 
216
- ### Displaying Attribution in SwiftUI
166
+ Pick the mark that matches the color scheme and link to the legal page:
217
167
 
218
168
  ```swift
219
- import SwiftUI
220
- import WeatherKit
221
-
222
- struct WeatherAttributionView: View {
223
- let attribution: WeatherAttribution
224
- @Environment(\.colorScheme) private var colorScheme
169
+ struct WeatherCredit: View {
170
+ let credit: WeatherAttribution
171
+ @Environment(\.colorScheme) private var scheme
225
172
 
226
173
  var body: some View {
227
- VStack {
228
- // Display the Apple Weather mark
229
- AsyncImage(url: markURL) { image in
230
- image
231
- .resizable()
232
- .scaledToFit()
233
- .frame(height: 20)
174
+ VStack(spacing: 6) {
175
+ AsyncImage(url: scheme == .dark ? credit.combinedMarkDarkURL : credit.combinedMarkLightURL) { mark in
176
+ mark.resizable().scaledToFit()
234
177
  } placeholder: {
235
- EmptyView()
178
+ Text(credit.serviceName).font(.caption2)
236
179
  }
180
+ .frame(height: 14)
237
181
 
238
- // Link to the legal attribution page
239
- Link("Weather data sources", destination: attribution.legalPageURL)
182
+ Link("Other data sources", destination: credit.legalPageURL)
240
183
  .font(.caption2)
241
- .foregroundStyle(.secondary)
242
184
  }
243
185
  }
244
-
245
- private var markURL: URL {
246
- colorScheme == .dark
247
- ? attribution.combinedMarkDarkURL
248
- : attribution.combinedMarkLightURL
249
- }
250
186
  }
251
187
  ```
252
188
 
253
- ### Attribution Properties
189
+ `WeatherAttribution` provides:
254
190
 
255
191
  | Property | Use |
256
- |---|---|
257
- | `combinedMarkLightURL` | Apple Weather mark for light backgrounds |
258
- | `combinedMarkDarkURL` | Apple Weather mark for dark backgrounds |
259
- | `squareMarkURL` | Square Apple Weather logo |
260
- | `legalPageURL` | URL to the legal attribution web page |
261
- | `legalAttributionText` | Text alternative when a web view is not feasible |
262
- | `serviceName` | Weather data provider name |
192
+ | --- | --- |
193
+ | `combinedMarkLightURL` | Mark for light backgrounds |
194
+ | `combinedMarkDarkURL` | Mark for dark backgrounds |
195
+ | `squareMarkURL` | Compact square mark |
196
+ | `legalPageURL` | Page listing data sources; link to it |
197
+ | `legalAttributionText` | Plain-text alternative when showing a web page is not practical |
198
+ | `serviceName` | The provider name, "Apple Weather" |
263
199
 
264
200
  ## Availability
265
201
 
266
- Check which weather datasets are available for a given location. Not all datasets
267
- are available in all countries.
202
+ Minute forecasts and alerts are not offered in every country. Ask before
203
+ building UI around them:
268
204
 
269
205
  ```swift
270
- func checkAvailability(for location: CLLocation) async throws {
271
- let availability = try await weatherService.weather(
272
- for: location,
273
- including: .availability
274
- )
275
-
276
- // Check specific dataset availability
277
- if availability.alertAvailability == .available {
278
- // Safe to fetch alerts
279
- }
280
-
281
- if availability.minuteAvailability == .available {
282
- // Minute forecast available for this region
283
- }
284
- }
285
- ```
286
-
287
- ## Common Mistakes
288
-
289
- ### DON'T: Ship without Apple Weather attribution
290
-
291
- Omitting attribution violates the WeatherKit terms of service and risks App Review
292
- rejection.
293
-
294
- ```swift
295
- // WRONG: Show weather data without attribution
296
- VStack {
297
- Text("72F, Sunny")
298
- }
299
-
300
- // CORRECT: Always include attribution
301
- VStack {
302
- Text("72F, Sunny")
303
- WeatherAttributionView(attribution: attribution)
304
- }
305
- ```
306
-
307
- ### DON'T: Fetch all datasets when you only need current conditions
308
-
309
- Each dataset query counts against your API quota. Fetch only what you display.
310
-
311
- ```swift
312
- // WRONG: Fetches everything
313
- let weather = try await weatherService.weather(for: location)
314
- let temp = weather.currentWeather.temperature
315
-
316
- // CORRECT: Fetch only current conditions
317
- let current = try await weatherService.weather(
318
- for: location,
319
- including: .current
320
- )
321
- let temp = current.temperature
322
- ```
323
-
324
- ### DON'T: Ignore minute forecast unavailability
325
-
326
- Minute forecasts return `nil` in unsupported regions. Force-unwrapping crashes.
327
-
328
- ```swift
329
- // WRONG: Force-unwrap minute forecast
330
- let minutes = try await weatherService.weather(for: location, including: .minute)
331
- for m in minutes! { ... } // Crash in unsupported regions
332
-
333
- // CORRECT: Handle nil
334
- if let minutes = try await weatherService.weather(for: location, including: .minute) {
335
- for m in minutes { ... }
336
- } else {
337
- // Minute forecast not available for this region
338
- }
339
- ```
340
-
341
- ### DON'T: Forget the WeatherKit entitlement
342
-
343
- Without the capability enabled, `WeatherService` calls throw at runtime.
344
-
345
- ```swift
346
- // WRONG: No WeatherKit capability configured
347
- let weather = try await weatherService.weather(for: location) // Throws
348
-
349
- // CORRECT: Enable WeatherKit in Xcode Signing & Capabilities
350
- // and in the Apple Developer portal for your App ID
351
- ```
352
-
353
- ### DON'T: Make repeated requests without caching
354
-
355
- Weather data updates every few minutes, not every second. Cache responses
356
- to stay within API quotas and improve performance.
357
-
358
- ```swift
359
- // WRONG: Fetch on every view appearance
360
- .task {
361
- let weather = try? await fetchWeather()
362
- }
363
-
364
- // CORRECT: Cache with a staleness interval
365
- actor WeatherCache {
366
- private var cached: CurrentWeather?
367
- private var lastFetch: Date?
368
-
369
- func current(for location: CLLocation) async throws -> CurrentWeather {
370
- if let cached, let lastFetch,
371
- Date.now.timeIntervalSince(lastFetch) < 600 {
372
- return cached
373
- }
374
- let fresh = try await WeatherService.shared.weather(
375
- for: location, including: .current
376
- )
377
- cached = fresh
378
- lastFetch = .now
379
- return fresh
380
- }
381
- }
206
+ let coverage = try await forecaster.weather(for: site, including: .availability)
207
+ let offersAlerts = coverage.alertAvailability == .available
208
+ let offersNextHour = coverage.minuteAvailability == .available
382
209
  ```
383
210
 
384
- ## Review Checklist
385
-
386
- - [ ] WeatherKit capability enabled in Xcode and Apple Developer portal
387
- - [ ] Active Apple Developer Program membership (required for WeatherKit)
388
- - [ ] Apple Weather attribution displayed wherever weather data appears
389
- - [ ] Attribution mark uses correct color scheme variant (light/dark)
390
- - [ ] Legal attribution page linked or `legalAttributionText` displayed
391
- - [ ] Only needed `WeatherQuery` datasets fetched (not full `weather(for:)` when unnecessary)
392
- - [ ] Minute forecast handled as optional (nil in unsupported regions)
393
- - [ ] Weather alerts checked for nil before iteration
394
- - [ ] Responses cached with a reasonable staleness interval (5-15 minutes)
395
- - [ ] `WeatherAvailability` checked before fetching region-limited datasets
396
- - [ ] Location permission requested before passing `CLLocation` to service
397
- - [ ] Temperature and measurements formatted with `Measurement.formatted()` for locale
211
+ Each is a `WeatherAvailability.AvailabilityKind`: `.available`,
212
+ `.temporarilyUnavailable`, `.unsupported` or `.unknown`.
213
+
214
+ ## Common mistakes
215
+
216
+ 1. **No attribution.** Leaving it out breaks the WeatherKit terms and is a
217
+ reason for App Review to reject the app.
218
+ 2. **Fetching everything to show one number.** `weather(for:)` returns every
219
+ dataset and each one counts against the quota. Use
220
+ `weather(for:including: .current)` when only current conditions appear.
221
+ 3. **Force-unwrapping the minute forecast.** It is `nil` in unsupported
222
+ regions and the app crashes there. Use `if let`.
223
+ 4. **Missing capability.** Without the capability and the portal switch,
224
+ `WeatherService` calls throw at runtime.
225
+ 5. **Refetching on every appearance.** Weather does not change second to
226
+ second. Cache results with a staleness window, for example an actor that
227
+ keeps entries for 600 seconds (see the reference file).
228
+
229
+ ## Review checklist
230
+
231
+ - [ ] WeatherKit capability added in Xcode and enabled in the portal
232
+ - [ ] Active developer program membership
233
+ - [ ] Attribution visible wherever weather data appears
234
+ - [ ] Attribution mark follows light and dark mode
235
+ - [ ] Legal page linked, or `legalAttributionText` shown
236
+ - [ ] Only the datasets the screen needs are requested
237
+ - [ ] Minute forecast treated as optional
238
+ - [ ] Alerts nil-checked
239
+ - [ ] Responses cached for 5 to 15 minutes
240
+ - [ ] `WeatherAvailability` checked before region-limited datasets
241
+ - [ ] Location permission granted before a device `CLLocation` is passed in
242
+ - [ ] Measurements displayed with `formatted()` so units follow the locale
398
243
 
399
244
  ## References
400
245
 
401
- - Extended patterns (SwiftUI dashboard, charts integration, historical statistics): [references/weatherkit-patterns.md](references/weatherkit-patterns.md)
402
- - [WeatherKit framework](https://sosumi.ai/documentation/weatherkit)
403
- - [WeatherService](https://sosumi.ai/documentation/weatherkit/weatherservice)
404
- - [WeatherAttribution](https://sosumi.ai/documentation/weatherkit/weatherattribution)
405
- - [WeatherQuery](https://sosumi.ai/documentation/weatherkit/weatherquery)
406
- - [CurrentWeather](https://sosumi.ai/documentation/weatherkit/currentweather)
407
- - [Forecast](https://sosumi.ai/documentation/weatherkit/forecast)
408
- - [HourWeather](https://sosumi.ai/documentation/weatherkit/hourweather)
409
- - [DayWeather](https://sosumi.ai/documentation/weatherkit/dayweather)
410
- - [WeatherAlert](https://sosumi.ai/documentation/weatherkit/weatheralert)
411
- - [WeatherAvailability](https://sosumi.ai/documentation/weatherkit/weatheravailability)
412
- - [Fetching weather forecasts with WeatherKit](https://sosumi.ai/documentation/weatherkit/fetching_weather_forecasts_with_weatherkit)
246
+ - [references/weatherkit-patterns.md](references/weatherkit-patterns.md)
247
+ - [WeatherKit](https://developer.apple.com/documentation/weatherkit)
248
+ - [WeatherService](https://developer.apple.com/documentation/weatherkit/weatherservice)
249
+ - [WeatherAttribution](https://developer.apple.com/documentation/weatherkit/weatherattribution)
250
+ - [WeatherQuery](https://developer.apple.com/documentation/weatherkit/weatherquery)
251
+ - [CurrentWeather](https://developer.apple.com/documentation/weatherkit/currentweather)
252
+ - [Forecast](https://developer.apple.com/documentation/weatherkit/forecast)
253
+ - [HourWeather](https://developer.apple.com/documentation/weatherkit/hourweather)
254
+ - [DayWeather](https://developer.apple.com/documentation/weatherkit/dayweather)
255
+ - [WeatherAlert](https://developer.apple.com/documentation/weatherkit/weatheralert)
256
+ - [WeatherAvailability](https://developer.apple.com/documentation/weatherkit/weatheravailability)
257
+ - [Fetching weather forecasts with WeatherKit](https://developer.apple.com/documentation/weatherkit/fetching_weather_forecasts_with_weatherkit)