@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.
- package/CHANGELOG.md +27 -0
- package/LICENSE +0 -10
- package/docs/facts.json +1 -1
- package/manifest.json +328 -329
- package/package.json +2 -2
- package/pipeline/multi-agent-refs/features/design-conformance.md +62 -64
- package/pipeline/scripts/_notices.mjs +12 -1
- package/pipeline/scripts/gen-skills-index.mjs +1 -1
- package/pipeline/skills/.skill-manifest.json +106 -106
- package/pipeline/skills/shared/README.md +71 -71
- package/pipeline/skills/shared/external/agent-introspection-debugging/SKILL.md +1 -0
- package/pipeline/skills/shared/external/alarmkit/SKILL.md +373 -381
- package/pipeline/skills/shared/external/alarmkit/evals/evals.json +23 -18
- package/pipeline/skills/shared/external/alarmkit/references/alarmkit-patterns.md +328 -378
- package/pipeline/skills/shared/external/android-architecture/SKILL.md +2 -0
- package/pipeline/skills/shared/external/android-performance/SKILL.md +2 -0
- package/pipeline/skills/shared/external/android-security/SKILL.md +2 -0
- package/pipeline/skills/shared/external/app-clips/SKILL.md +260 -160
- package/pipeline/skills/shared/external/app-clips/evals/evals.json +27 -27
- package/pipeline/skills/shared/external/app-clips/references/data-handoff-notifications-location.md +150 -83
- package/pipeline/skills/shared/external/app-clips/references/routing-and-experiences.md +135 -83
- package/pipeline/skills/shared/external/app-clips/references/size-capabilities-and-promotion.md +143 -85
- package/pipeline/skills/shared/external/app-intents/SKILL.md +302 -304
- package/pipeline/skills/shared/external/app-intents/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/app-intents/references/appintents-advanced.md +594 -894
- package/pipeline/skills/shared/external/app-store-optimization/SKILL.md +339 -277
- package/pipeline/skills/shared/external/app-store-optimization/evals/evals.json +27 -23
- package/pipeline/skills/shared/external/app-store-optimization/references/keyword-research-methodology.md +105 -122
- package/pipeline/skills/shared/external/app-store-optimization/references/product-page-variants.md +143 -166
- package/pipeline/skills/shared/external/app-store-review/SKILL.md +307 -326
- package/pipeline/skills/shared/external/app-store-review/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/app-store-review/references/privacy-manifest.md +105 -67
- package/pipeline/skills/shared/external/app-store-review/references/review-checklists.md +114 -101
- package/pipeline/skills/shared/external/apple-on-device-ai/SKILL.md +333 -360
- package/pipeline/skills/shared/external/apple-on-device-ai/evals/evals.json +24 -27
- package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-conversion.md +215 -322
- package/pipeline/skills/shared/external/apple-on-device-ai/references/coreml-optimization.md +161 -256
- package/pipeline/skills/shared/external/apple-on-device-ai/references/foundation-models.md +277 -387
- package/pipeline/skills/shared/external/apple-on-device-ai/references/mlx-swift.md +196 -210
- package/pipeline/skills/shared/external/authentication/SKILL.md +265 -381
- package/pipeline/skills/shared/external/authentication/evals/evals.json +25 -25
- package/pipeline/skills/shared/external/authentication/references/keychain-biometric.md +133 -178
- package/pipeline/skills/shared/external/authentication/references/passkeys.md +111 -147
- package/pipeline/skills/shared/external/avkit/SKILL.md +267 -364
- package/pipeline/skills/shared/external/avkit/evals/evals.json +26 -26
- package/pipeline/skills/shared/external/avkit/references/avkit-patterns.md +375 -493
- package/pipeline/skills/shared/external/background-processing/SKILL.md +270 -382
- package/pipeline/skills/shared/external/background-processing/evals/evals.json +22 -22
- package/pipeline/skills/shared/external/background-processing/references/background-task-patterns.md +169 -317
- package/pipeline/skills/shared/external/backlog/BACKLOG.md +1 -1
- package/pipeline/skills/shared/external/backlog/SKILL.md +56 -33
- package/pipeline/skills/shared/external/callkit-voip/SKILL.md +290 -371
- package/pipeline/skills/shared/external/callkit-voip/evals/evals.json +24 -24
- package/pipeline/skills/shared/external/callkit-voip/references/callkit-patterns.md +175 -343
- package/pipeline/skills/shared/external/ci-cd-pipelines/SKILL.md +1 -0
- package/pipeline/skills/shared/external/cloudkit-sync/SKILL.md +292 -381
- package/pipeline/skills/shared/external/cloudkit-sync/evals/evals.json +33 -30
- package/pipeline/skills/shared/external/cloudkit-sync/references/cloudkit-patterns.md +227 -355
- package/pipeline/skills/shared/external/compose-components/SKILL.md +2 -0
- package/pipeline/skills/shared/external/compose-navigation/SKILL.md +3 -2
- package/pipeline/skills/shared/external/compose-testing/SKILL.md +2 -0
- package/pipeline/skills/shared/external/contacts-framework/SKILL.md +197 -346
- package/pipeline/skills/shared/external/contacts-framework/evals/evals.json +19 -21
- package/pipeline/skills/shared/external/contacts-framework/references/contacts-patterns.md +169 -308
- package/pipeline/skills/shared/external/core-bluetooth/SKILL.md +226 -376
- package/pipeline/skills/shared/external/core-bluetooth/evals/evals.json +25 -22
- package/pipeline/skills/shared/external/core-bluetooth/references/ble-patterns.md +257 -337
- package/pipeline/skills/shared/external/core-data/SKILL.md +292 -368
- package/pipeline/skills/shared/external/core-data/evals/evals.json +30 -27
- package/pipeline/skills/shared/external/core-motion/SKILL.md +235 -324
- package/pipeline/skills/shared/external/core-motion/evals/evals.json +31 -27
- package/pipeline/skills/shared/external/core-motion/references/motion-patterns.md +210 -310
- package/pipeline/skills/shared/external/core-nfc/SKILL.md +292 -366
- package/pipeline/skills/shared/external/core-nfc/evals/evals.json +22 -24
- package/pipeline/skills/shared/external/core-nfc/references/nfc-patterns.md +233 -329
- package/pipeline/skills/shared/external/coreml/SKILL.md +323 -367
- package/pipeline/skills/shared/external/coreml/evals/evals.json +24 -21
- package/pipeline/skills/shared/external/coreml/references/coreml-swift-integration.md +562 -565
- package/pipeline/skills/shared/external/council/SKILL.md +1 -0
- package/pipeline/skills/shared/external/cryptokit/SKILL.md +253 -394
- package/pipeline/skills/shared/external/cryptokit/evals/evals.json +20 -18
- package/pipeline/skills/shared/external/cryptokit/references/cryptokit-patterns.md +299 -488
- package/pipeline/skills/shared/external/css-modern/SKILL.md +1 -0
- package/pipeline/skills/shared/external/database-patterns/SKILL.md +1 -0
- package/pipeline/skills/shared/external/debugging-instruments/SKILL.md +270 -323
- package/pipeline/skills/shared/external/debugging-instruments/evals/evals.json +27 -30
- package/pipeline/skills/shared/external/debugging-instruments/references/instruments-guide.md +167 -315
- package/pipeline/skills/shared/external/debugging-instruments/references/lldb-patterns.md +140 -193
- package/pipeline/skills/shared/external/device-integrity/SKILL.md +230 -353
- package/pipeline/skills/shared/external/device-integrity/evals/evals.json +25 -21
- package/pipeline/skills/shared/external/device-integrity/references/device-integrity-patterns.md +159 -197
- package/pipeline/skills/shared/external/energykit/SKILL.md +225 -392
- package/pipeline/skills/shared/external/energykit/evals/evals.json +29 -28
- package/pipeline/skills/shared/external/energykit/references/energykit-patterns.md +174 -470
- package/pipeline/skills/shared/external/eventkit-calendar/SKILL.md +261 -383
- package/pipeline/skills/shared/external/eventkit-calendar/evals/evals.json +25 -22
- package/pipeline/skills/shared/external/eventkit-calendar/references/eventkit-patterns.md +165 -268
- package/pipeline/skills/shared/external/evidence-github/SKILL.md +2 -0
- package/pipeline/skills/shared/external/evidence-registry/SKILL.md +2 -0
- package/pipeline/skills/shared/external/gradle-kotlin-dsl/SKILL.md +2 -0
- package/pipeline/skills/shared/external/healthkit/SKILL.md +252 -303
- package/pipeline/skills/shared/external/healthkit/evals/evals.json +24 -23
- package/pipeline/skills/shared/external/healthkit/references/healthkit-patterns.md +369 -523
- package/pipeline/skills/shared/external/homekit-matter/SKILL.md +233 -348
- package/pipeline/skills/shared/external/homekit-matter/evals/evals.json +27 -22
- package/pipeline/skills/shared/external/homekit-matter/references/matter-commissioning.md +199 -305
- package/pipeline/skills/shared/external/html-semantic/SKILL.md +1 -0
- package/pipeline/skills/shared/external/humanizer/SKILL.md +1 -0
- package/pipeline/skills/shared/external/ios-accessibility/SKILL.md +368 -340
- package/pipeline/skills/shared/external/ios-accessibility/evals/evals.json +28 -27
- package/pipeline/skills/shared/external/ios-accessibility/references/a11y-patterns.md +314 -260
- package/pipeline/skills/shared/external/ios-accessibility/references/media-accessibility.md +97 -67
- package/pipeline/skills/shared/external/ios-accessibility/references/nutrition-labels.md +165 -101
- package/pipeline/skills/shared/external/ios-coding-standard/SKILL.md +1 -0
- package/pipeline/skills/shared/external/ios-localization/SKILL.md +258 -371
- package/pipeline/skills/shared/external/ios-localization/evals/evals.json +23 -23
- package/pipeline/skills/shared/external/ios-localization/references/formatstyle-locale.md +283 -491
- package/pipeline/skills/shared/external/ios-localization/references/string-catalogs.md +313 -440
- package/pipeline/skills/shared/external/ios-module-structure/SKILL.md +1 -0
- package/pipeline/skills/shared/external/ios-networking/SKILL.md +265 -341
- package/pipeline/skills/shared/external/ios-networking/evals/evals.json +24 -24
- package/pipeline/skills/shared/external/ios-networking/references/background-websocket.md +425 -652
- package/pipeline/skills/shared/external/ios-networking/references/file-storage-patterns.md +143 -285
- package/pipeline/skills/shared/external/ios-networking/references/lightweight-clients.md +93 -53
- package/pipeline/skills/shared/external/ios-networking/references/network-framework.md +231 -456
- package/pipeline/skills/shared/external/ios-networking/references/urlsession-patterns.md +517 -784
- package/pipeline/skills/shared/external/ios-security/SKILL.md +2 -0
- package/pipeline/skills/shared/external/ios-simulator/SKILL.md +265 -393
- package/pipeline/skills/shared/external/ios-simulator/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/ios-simulator/references/simctl-commands.md +177 -270
- package/pipeline/skills/shared/external/live-activities/SKILL.md +318 -360
- package/pipeline/skills/shared/external/live-activities/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/live-activities/references/activitykit-patterns.md +478 -710
- package/pipeline/skills/shared/external/localization-reuse-map/SKILL.md +91 -283
- package/pipeline/skills/shared/external/localization-reuse-map/reference/format-and-output.md +119 -151
- package/pipeline/skills/shared/external/localization-reuse-map/reference/publish-and-snapshot.md +60 -90
- package/pipeline/skills/shared/external/localization-reuse-map/reference/sources-and-recipes.md +119 -156
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/build-artifact.py +726 -787
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/build-spreadsheet.py +253 -288
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/fetch-annotations.py +243 -304
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/fetch-legacy-labels.py +88 -104
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/publish-confluence.py +181 -235
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/render-key-shots.py +198 -263
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/render-overlay.py +461 -466
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/resolve-legacy-values.py +145 -151
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/resolve-new-values.py +123 -141
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/scan-screen-keys.py +146 -157
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/snapshot-resources.sh +22 -19
- package/pipeline/skills/shared/external/localization-reuse-map/scripts/verify-map.py +156 -140
- package/pipeline/skills/shared/external/mapkit-location/SKILL.md +295 -267
- package/pipeline/skills/shared/external/mapkit-location/evals/evals.json +28 -24
- package/pipeline/skills/shared/external/mapkit-location/references/mapkit-corelocation-patterns.md +378 -532
- package/pipeline/skills/shared/external/mapkit-location/references/mapkit-patterns.md +397 -499
- package/pipeline/skills/shared/external/metrickit-diagnostics/SKILL.md +165 -348
- package/pipeline/skills/shared/external/metrickit-diagnostics/evals/evals.json +26 -23
- package/pipeline/skills/shared/external/metrickit-diagnostics/references/metrickit-patterns.md +123 -130
- package/pipeline/skills/shared/external/musickit-audio/SKILL.md +189 -315
- package/pipeline/skills/shared/external/musickit-audio/evals/evals.json +22 -21
- package/pipeline/skills/shared/external/musickit-audio/references/musickit-patterns.md +181 -270
- package/pipeline/skills/shared/external/natural-language/SKILL.md +188 -340
- package/pipeline/skills/shared/external/natural-language/evals/evals.json +21 -21
- package/pipeline/skills/shared/external/natural-language/references/translation-patterns.md +171 -225
- package/pipeline/skills/shared/external/nextjs-app-router/SKILL.md +1 -0
- package/pipeline/skills/shared/external/passkit-wallet/SKILL.md +258 -392
- package/pipeline/skills/shared/external/passkit-wallet/evals/evals.json +30 -29
- package/pipeline/skills/shared/external/passkit-wallet/references/wallet-passes.md +164 -231
- package/pipeline/skills/shared/external/pdfkit/SKILL.md +312 -344
- package/pipeline/skills/shared/external/pdfkit/evals/evals.json +19 -19
- package/pipeline/skills/shared/external/pdfkit/references/pdfkit-patterns.md +413 -624
- package/pipeline/skills/shared/external/pencilkit-drawing/SKILL.md +242 -358
- package/pipeline/skills/shared/external/pencilkit-drawing/evals/evals.json +25 -21
- package/pipeline/skills/shared/external/pencilkit-drawing/references/pencilkit-patterns.md +161 -226
- package/pipeline/skills/shared/external/permissionkit/SKILL.md +282 -400
- package/pipeline/skills/shared/external/permissionkit/evals/evals.json +27 -30
- package/pipeline/skills/shared/external/permissionkit/references/permissionkit-patterns.md +237 -350
- package/pipeline/skills/shared/external/photos-camera-media/SKILL.md +276 -325
- package/pipeline/skills/shared/external/photos-camera-media/references/av-playback.md +299 -545
- package/pipeline/skills/shared/external/photos-camera-media/references/camera-capture.md +344 -588
- package/pipeline/skills/shared/external/photos-camera-media/references/image-loading-caching.md +316 -660
- package/pipeline/skills/shared/external/photos-camera-media/references/photokit-patterns.md +270 -416
- package/pipeline/skills/shared/external/play-store-review/SKILL.md +2 -0
- package/pipeline/skills/shared/external/push-notifications/SKILL.md +312 -340
- package/pipeline/skills/shared/external/push-notifications/evals/evals.json +27 -26
- package/pipeline/skills/shared/external/push-notifications/references/notification-patterns.md +328 -485
- package/pipeline/skills/shared/external/push-notifications/references/rich-notifications.md +327 -560
- package/pipeline/skills/shared/external/python-patterns/SKILL.md +1 -0
- package/pipeline/skills/shared/external/react-best-practices/SKILL.md +1 -0
- package/pipeline/skills/shared/external/realitykit-ar/SKILL.md +218 -410
- package/pipeline/skills/shared/external/realitykit-ar/evals/evals.json +24 -27
- package/pipeline/skills/shared/external/realitykit-ar/references/realitykit-patterns.md +221 -348
- package/pipeline/skills/shared/external/rest-api-design/SKILL.md +1 -0
- package/pipeline/skills/shared/external/retrofit-networking/SKILL.md +2 -0
- package/pipeline/skills/shared/external/room-database/SKILL.md +2 -0
- package/pipeline/skills/shared/external/search-first/SKILL.md +1 -0
- package/pipeline/skills/shared/external/shareplay-activities/SKILL.md +222 -393
- package/pipeline/skills/shared/external/shareplay-activities/evals/evals.json +23 -24
- package/pipeline/skills/shared/external/shareplay-activities/references/shareplay-patterns.md +280 -420
- package/pipeline/skills/shared/external/signal-community/SKILL.md +2 -0
- package/pipeline/skills/shared/external/skill-creator/SKILL.md +80 -41
- package/pipeline/skills/shared/external/skill-creator/audit.md +63 -59
- package/pipeline/skills/shared/external/skill-creator/checklist.md +28 -20
- package/pipeline/skills/shared/external/skill-creator/examples.md +40 -40
- package/pipeline/skills/shared/external/skill-creator/label-check.md +48 -36
- package/pipeline/skills/shared/external/skill-creator/scripts/audit-panel.js +91 -100
- package/pipeline/skills/shared/external/skill-creator/template.md +51 -39
- package/pipeline/skills/shared/external/speech-recognition/SKILL.md +217 -421
- package/pipeline/skills/shared/external/speech-recognition/evals/evals.json +23 -26
- package/pipeline/skills/shared/external/speech-recognition/references/speechanalyzer-patterns.md +133 -125
- package/pipeline/skills/shared/external/storekit/SKILL.md +228 -204
- package/pipeline/skills/shared/external/storekit/evals/evals.json +27 -24
- package/pipeline/skills/shared/external/storekit/references/app-review-guidelines.md +98 -109
- package/pipeline/skills/shared/external/storekit/references/core-patterns.md +298 -242
- package/pipeline/skills/shared/external/storekit/references/storekit-advanced.md +356 -649
- package/pipeline/skills/shared/external/swift-api-design-guidelines/SKILL.md +274 -399
- package/pipeline/skills/shared/external/swift-api-design-guidelines/evals/evals.json +22 -24
- package/pipeline/skills/shared/external/swift-api-design-guidelines/references/argument-labels-and-parameters.md +107 -108
- package/pipeline/skills/shared/external/swift-api-design-guidelines/references/conventions-and-special-rules.md +93 -165
- package/pipeline/skills/shared/external/swift-api-design-guidelines/references/naming-and-clarity.md +99 -137
- package/pipeline/skills/shared/external/swift-api-design-guidelines/references/side-effects-and-mutating-pairs.md +77 -120
- package/pipeline/skills/shared/external/swift-architecture/SKILL.md +334 -350
- package/pipeline/skills/shared/external/swift-architecture/evals/evals.json +22 -22
- package/pipeline/skills/shared/external/swift-charts/SKILL.md +208 -394
- package/pipeline/skills/shared/external/swift-charts/evals/evals.json +27 -30
- package/pipeline/skills/shared/external/swift-charts/references/charts-patterns.md +351 -762
- package/pipeline/skills/shared/external/swift-codable/SKILL.md +339 -343
- package/pipeline/skills/shared/external/swift-codable/evals/evals.json +20 -20
- package/pipeline/skills/shared/external/swift-concurrency/SKILL.md +303 -351
- package/pipeline/skills/shared/external/swift-concurrency/evals/evals.json +27 -24
- package/pipeline/skills/shared/external/swift-concurrency/references/approachable-concurrency.md +65 -80
- package/pipeline/skills/shared/external/swift-concurrency/references/async-algorithms.md +48 -84
- package/pipeline/skills/shared/external/swift-concurrency/references/bridging-interop.md +134 -79
- package/pipeline/skills/shared/external/swift-concurrency/references/concurrency-patterns.md +145 -167
- package/pipeline/skills/shared/external/swift-concurrency/references/diagnostics.md +62 -50
- package/pipeline/skills/shared/external/swift-concurrency/references/swiftui-concurrency.md +92 -121
- package/pipeline/skills/shared/external/swift-concurrency/references/synchronization-primitives.md +177 -241
- package/pipeline/skills/shared/external/swift-formatstyle/SKILL.md +258 -234
- package/pipeline/skills/shared/external/swift-language/SKILL.md +342 -382
- package/pipeline/skills/shared/external/swift-language/evals/evals.json +24 -27
- package/pipeline/skills/shared/external/swift-language/references/swift-attributes-interop.md +79 -56
- package/pipeline/skills/shared/external/swift-language/references/swift-patterns-extended.md +297 -340
- package/pipeline/skills/shared/external/swift-security/SKILL.md +180 -161
- package/pipeline/skills/shared/external/swift-security/evals/evals.json +25 -25
- package/pipeline/skills/shared/external/swift-security/references/biometric-authentication.md +314 -469
- package/pipeline/skills/shared/external/swift-security/references/certificate-trust.md +408 -476
- package/pipeline/skills/shared/external/swift-security/references/common-anti-patterns.md +260 -530
- package/pipeline/skills/shared/external/swift-security/references/compliance-owasp-mapping.md +270 -477
- package/pipeline/skills/shared/external/swift-security/references/credential-storage-patterns.md +573 -571
- package/pipeline/skills/shared/external/swift-security/references/cryptokit-public-key.md +370 -441
- package/pipeline/skills/shared/external/swift-security/references/cryptokit-symmetric.md +332 -433
- package/pipeline/skills/shared/external/swift-security/references/keychain-access-control.md +346 -468
- package/pipeline/skills/shared/external/swift-security/references/keychain-fundamentals.md +352 -472
- package/pipeline/skills/shared/external/swift-security/references/keychain-item-classes.md +431 -432
- package/pipeline/skills/shared/external/swift-security/references/keychain-sharing.md +328 -425
- package/pipeline/skills/shared/external/swift-security/references/migration-legacy-stores.md +341 -579
- package/pipeline/skills/shared/external/swift-security/references/secure-enclave.md +396 -457
- package/pipeline/skills/shared/external/swift-security/references/testing-security-code.md +354 -614
- package/pipeline/skills/shared/external/swift-testing/SKILL.md +188 -175
- package/pipeline/skills/shared/external/swift-testing/evals/evals.json +26 -24
- package/pipeline/skills/shared/external/swift-testing/references/testing-advanced.md +80 -84
- package/pipeline/skills/shared/external/swift-testing/references/testing-patterns.md +317 -433
- package/pipeline/skills/shared/external/swiftdata/SKILL.md +392 -256
- package/pipeline/skills/shared/external/swiftdata/evals/evals.json +24 -24
- package/pipeline/skills/shared/external/swiftdata/references/core-data-coexistence.md +206 -402
- package/pipeline/skills/shared/external/swiftdata/references/indexing.md +59 -52
- package/pipeline/skills/shared/external/swiftdata/references/predicate-pitfalls.md +57 -33
- package/pipeline/skills/shared/external/swiftdata/references/swiftdata-advanced.md +354 -747
- package/pipeline/skills/shared/external/swiftdata/references/swiftdata-queries.md +300 -508
- package/pipeline/skills/shared/external/swiftlint/SKILL.md +175 -226
- package/pipeline/skills/shared/external/swiftlint/references/adoption-and-configuration.md +141 -208
- package/pipeline/skills/shared/external/swiftlint/references/custom-rules-and-analyze.md +100 -109
- package/pipeline/skills/shared/external/swiftlint/references/plugins-run-scripts-and-integrations.md +159 -179
- package/pipeline/skills/shared/external/swiftlint/references/rule-reference.md +383 -18
- package/pipeline/skills/shared/external/swiftlint/references/rules-suppressions-and-baselines.md +143 -229
- package/pipeline/skills/shared/external/swiftui-animation/SKILL.md +283 -366
- package/pipeline/skills/shared/external/swiftui-animation/references/animation-advanced.md +396 -608
- package/pipeline/skills/shared/external/swiftui-animation/references/core-animation-bridge.md +336 -385
- package/pipeline/skills/shared/external/swiftui-gestures/SKILL.md +239 -349
- package/pipeline/skills/shared/external/swiftui-gestures/references/gesture-patterns.md +228 -310
- package/pipeline/skills/shared/external/swiftui-layout-components/SKILL.md +260 -249
- package/pipeline/skills/shared/external/swiftui-layout-components/references/form.md +92 -74
- package/pipeline/skills/shared/external/swiftui-layout-components/references/grids.md +112 -177
- package/pipeline/skills/shared/external/swiftui-layout-components/references/list.md +61 -64
- package/pipeline/skills/shared/external/swiftui-layout-components/references/scrollview.md +94 -134
- package/pipeline/skills/shared/external/swiftui-liquid-glass/SKILL.md +193 -225
- package/pipeline/skills/shared/external/swiftui-liquid-glass/references/liquid-glass.md +173 -327
- package/pipeline/skills/shared/external/swiftui-navigation/SKILL.md +193 -168
- package/pipeline/skills/shared/external/swiftui-navigation/references/deeplinks.md +127 -150
- package/pipeline/skills/shared/external/swiftui-navigation/references/navigationstack.md +132 -133
- package/pipeline/skills/shared/external/swiftui-navigation/references/sheets.md +152 -117
- package/pipeline/skills/shared/external/swiftui-navigation/references/tabview.md +106 -140
- package/pipeline/skills/shared/external/swiftui-patterns/SKILL.md +316 -252
- package/pipeline/skills/shared/external/swiftui-patterns/references/architecture-patterns.md +341 -332
- package/pipeline/skills/shared/external/swiftui-patterns/references/deprecated-migration.md +547 -854
- package/pipeline/skills/shared/external/swiftui-patterns/references/design-polish.md +485 -537
- package/pipeline/skills/shared/external/swiftui-patterns/references/platform-and-sharing.md +417 -499
- package/pipeline/skills/shared/external/swiftui-performance/SKILL.md +213 -376
- package/pipeline/skills/shared/external/swiftui-performance/references/demystify-swiftui-performance-wwdc23.md +86 -175
- package/pipeline/skills/shared/external/swiftui-performance/references/optimizing-swiftui-performance-instruments.md +89 -195
- package/pipeline/skills/shared/external/swiftui-performance/references/understanding-hangs-in-your-app.md +95 -182
- package/pipeline/skills/shared/external/swiftui-performance/references/understanding-improving-swiftui-performance.md +71 -149
- package/pipeline/skills/shared/external/swiftui-performance/references/wwdc-session-sources.md +21 -27
- package/pipeline/skills/shared/external/swiftui-uikit-interop/SKILL.md +303 -295
- package/pipeline/skills/shared/external/swiftui-uikit-interop/references/hosting-migration.md +204 -387
- package/pipeline/skills/shared/external/swiftui-uikit-interop/references/representable-recipes.md +469 -683
- package/pipeline/skills/shared/external/swiftui-webkit/SKILL.md +140 -186
- package/pipeline/skills/shared/external/swiftui-webkit/references/loading-and-observation.md +75 -86
- package/pipeline/skills/shared/external/swiftui-webkit/references/local-content-and-custom-schemes.md +63 -60
- package/pipeline/skills/shared/external/swiftui-webkit/references/migration-and-fallbacks.md +69 -137
- package/pipeline/skills/shared/external/swiftui-webkit/references/navigation-and-javascript.md +95 -67
- package/pipeline/skills/shared/external/tailwind-css/SKILL.md +1 -0
- package/pipeline/skills/shared/external/testing-backend/SKILL.md +1 -0
- package/pipeline/skills/shared/external/tipkit/SKILL.md +220 -335
- package/pipeline/skills/shared/external/tipkit/references/tipkit-patterns.md +356 -494
- package/pipeline/skills/shared/external/typescript-patterns/SKILL.md +1 -0
- package/pipeline/skills/shared/external/vision-framework/SKILL.md +260 -375
- package/pipeline/skills/shared/external/vision-framework/references/vision-requests.md +393 -515
- package/pipeline/skills/shared/external/vision-framework/references/visionkit-scanner.md +363 -539
- package/pipeline/skills/shared/external/vue-composition/SKILL.md +1 -0
- package/pipeline/skills/shared/external/weatherkit/SKILL.md +152 -310
- package/pipeline/skills/shared/external/weatherkit/references/weatherkit-patterns.md +288 -407
- package/pipeline/skills/shared/external/web-accessibility/SKILL.md +1 -0
- package/pipeline/skills/shared/external/web-performance/SKILL.md +1 -0
- package/pipeline/skills/shared/external/web-testing/SKILL.md +1 -0
- package/pipeline/skills/shared/external/widgetkit/SKILL.md +216 -288
- package/pipeline/skills/shared/external/widgetkit/references/widgetkit-advanced.md +414 -719
- package/pipeline/skills/shared/external/NOTICE-swift-ios-skills.md +0 -39
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
name: vue-composition
|
|
3
3
|
description: "Vue 3 Composition API: ref, reactive, computed, watch, composables, Pinia state management, Vue Router 4, script setup. Use when building or reviewing Vue 3 work with the Composition API, composables or Pinia."
|
|
4
4
|
metadata:
|
|
5
|
+
source: multi-agent-pipeline
|
|
5
6
|
tags: [vue, composition-api, pinia, vue-router, frontend, javascript]
|
|
6
7
|
version: "2025.1"
|
|
7
8
|
---
|
|
@@ -1,412 +1,254 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: weatherkit
|
|
3
|
-
description: "
|
|
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:
|
|
5
|
+
source: multi-agent-pipeline
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# WeatherKit
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
attribution
|
|
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
|
-
|
|
15
|
-
|
|
16
|
-
-
|
|
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
|
|
21
|
+
### Project configuration
|
|
30
22
|
|
|
31
|
-
1.
|
|
32
|
-
2.
|
|
33
|
-
|
|
34
|
-
|
|
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
|
-
###
|
|
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
|
-
|
|
39
|
+
`WeatherService` is `Sendable`, so one instance can be used from any task or
|
|
40
|
+
actor.
|
|
41
|
+
|
|
42
|
+
## Fetching current weather
|
|
44
43
|
|
|
45
|
-
|
|
46
|
-
thread-safe.
|
|
44
|
+
The plain call returns every dataset in a `Weather` value:
|
|
47
45
|
|
|
48
46
|
```swift
|
|
49
|
-
let
|
|
50
|
-
|
|
51
|
-
let
|
|
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
|
-
|
|
52
|
+
`CurrentWeather` fields you will use most:
|
|
55
53
|
|
|
56
|
-
|
|
57
|
-
|
|
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
|
-
|
|
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
|
|
69
|
+
### Hourly
|
|
81
70
|
|
|
82
|
-
|
|
71
|
+
By default the hourly forecast covers 25 consecutive hours starting with the
|
|
72
|
+
current hour. `hourlyForecast` is a `Forecast<HourWeather>`:
|
|
83
73
|
|
|
84
74
|
```swift
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
return weather.hourlyForecast
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// Iterate hours
|
|
91
|
-
for hour in hourlyForecast {
|
|
92
|
-
print("\(hour.date): \(hour.temperature.formatted()), \(hour.condition)")
|
|
75
|
+
let timeline = report.hourlyForecast.map { slot in
|
|
76
|
+
(slot.date.formatted(.dateTime.hour()), slot.temperature.formatted(), slot.condition.description)
|
|
93
77
|
}
|
|
94
78
|
```
|
|
95
79
|
|
|
96
|
-
### Daily
|
|
80
|
+
### Daily
|
|
97
81
|
|
|
98
|
-
|
|
82
|
+
By default the daily forecast covers 10 consecutive days starting today.
|
|
83
|
+
`dailyForecast` is a `Forecast<DayWeather>`:
|
|
99
84
|
|
|
100
85
|
```swift
|
|
101
|
-
|
|
102
|
-
let
|
|
103
|
-
|
|
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)")
|
|
86
|
+
for day in report.dailyForecast {
|
|
87
|
+
let range = "\(day.lowTemperature.formatted()) to \(day.highTemperature.formatted())"
|
|
88
|
+
let rain = day.precipitationChance.formatted(.percent)
|
|
89
|
+
rows.append("\(day.condition.description), \(range), rain \(rain)")
|
|
110
90
|
}
|
|
111
91
|
```
|
|
112
92
|
|
|
113
|
-
###
|
|
114
|
-
|
|
115
|
-
Request forecasts for specific date ranges using `WeatherQuery`.
|
|
93
|
+
### A custom range
|
|
116
94
|
|
|
117
95
|
```swift
|
|
118
|
-
func
|
|
119
|
-
let
|
|
120
|
-
let
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
for:
|
|
124
|
-
including: .daily(startDate:
|
|
96
|
+
func nextWeek(at site: CLLocation) async throws -> Forecast<DayWeather>? {
|
|
97
|
+
let weekStart = Date.now
|
|
98
|
+
guard let weekEnd = Calendar.current.date(byAdding: DateComponents(day: 7), to: weekStart) else { return nil }
|
|
99
|
+
let service = WeatherService.shared
|
|
100
|
+
return try await service.weather(
|
|
101
|
+
for: site,
|
|
102
|
+
including: .daily(startDate: weekStart, endDate: weekEnd)
|
|
125
103
|
)
|
|
126
|
-
return forecast
|
|
127
104
|
}
|
|
128
105
|
```
|
|
129
106
|
|
|
130
|
-
|
|
107
|
+
`.hourly(startDate:endDate:)` works the same way for hours.
|
|
131
108
|
|
|
132
|
-
|
|
133
|
-
and affected regions.
|
|
109
|
+
## Weather alerts
|
|
134
110
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
let weather = try await weatherService.weather(for: location)
|
|
138
|
-
return weather.weatherAlerts
|
|
139
|
-
}
|
|
111
|
+
`weatherAlerts` is `[WeatherAlert]?`; it is `nil` where alerts are not
|
|
112
|
+
provided.
|
|
140
113
|
|
|
141
|
-
|
|
142
|
-
if let alerts = weatherAlerts {
|
|
114
|
+
```swift
|
|
115
|
+
if let alerts = report.weatherAlerts {
|
|
143
116
|
for alert in alerts {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
if let detailsURL = alert.detailsURL {
|
|
148
|
-
// Link to full alert details
|
|
149
|
-
}
|
|
117
|
+
// alert.summary: String, alert.severity: WeatherSeverity,
|
|
118
|
+
// alert.region: String?, alert.detailsURL: URL, alert.source: String
|
|
119
|
+
banners.append(alert.summary)
|
|
150
120
|
}
|
|
151
121
|
}
|
|
152
122
|
```
|
|
153
123
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
Fetch only the datasets you need to minimize API usage and response size. Each
|
|
157
|
-
`WeatherQuery` type maps to one dataset.
|
|
124
|
+
`detailsURL` is not optional; link to it so users can read the full notice
|
|
125
|
+
from the issuing agency.
|
|
158
126
|
|
|
159
|
-
|
|
127
|
+
## Selective queries
|
|
160
128
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
for: location,
|
|
164
|
-
including: .current
|
|
165
|
-
)
|
|
166
|
-
// current is CurrentWeather
|
|
167
|
-
```
|
|
168
|
-
|
|
169
|
-
### Multiple Datasets
|
|
129
|
+
Ask only for what the screen shows. Each `WeatherQuery` maps to one dataset,
|
|
130
|
+
and each dataset is a request against the quota and more bytes over the wire.
|
|
170
131
|
|
|
171
132
|
```swift
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
including: .current, .hourly, .daily
|
|
175
|
-
)
|
|
176
|
-
// current: CurrentWeather, hourly: Forecast<HourWeather>, daily: Forecast<DayWeather>
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
### Minute Forecast
|
|
133
|
+
// One dataset: the return type is the dataset itself.
|
|
134
|
+
let nowOnly: CurrentWeather = try await forecaster.weather(for: site, including: .current)
|
|
180
135
|
|
|
181
|
-
|
|
182
|
-
|
|
136
|
+
// Several datasets: the results come back as a tuple, in the order requested.
|
|
137
|
+
let (now, hours, days) = try await forecaster.weather(for: site, including: .current, .hourly, .daily)
|
|
183
138
|
|
|
184
|
-
|
|
185
|
-
let
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
)
|
|
189
|
-
// minuteForecast: Forecast<MinuteWeather>? (nil if unavailable)
|
|
139
|
+
// Next-hour precipitation, minute by minute. Only some regions have it.
|
|
140
|
+
if let nextHour = try await forecaster.weather(for: site, including: .minute) {
|
|
141
|
+
rainStartsSoon = nextHour.contains { $0.precipitationChance > 0.5 }
|
|
142
|
+
}
|
|
190
143
|
```
|
|
191
144
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
|
195
|
-
|
|
196
|
-
| `.current` | `CurrentWeather` | Current observed conditions |
|
|
197
|
-
| `.hourly` | `Forecast<HourWeather>` | 25 hours from current hour |
|
|
145
|
+
| Query | Result type | Notes |
|
|
146
|
+
| --- | --- | --- |
|
|
147
|
+
| `.current` | `CurrentWeather` | |
|
|
148
|
+
| `.hourly` | `Forecast<HourWeather>` | 25 hours from now |
|
|
198
149
|
| `.daily` | `Forecast<DayWeather>` | 10 days from today |
|
|
199
|
-
| `.minute` | `Forecast<MinuteWeather>?` |
|
|
200
|
-
| `.alerts` | `[WeatherAlert]?` |
|
|
201
|
-
| `.availability` | `WeatherAvailability` |
|
|
150
|
+
| `.minute` | `Forecast<MinuteWeather>?` | `nil` where unsupported |
|
|
151
|
+
| `.alerts` | `[WeatherAlert]?` | `nil` where unsupported |
|
|
152
|
+
| `.availability` | `WeatherAvailability` | Which region-limited datasets exist here |
|
|
202
153
|
|
|
203
154
|
## Attribution
|
|
204
155
|
|
|
205
|
-
Apple
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
### Fetching Attribution
|
|
156
|
+
Showing Apple Weather attribution is a legal requirement of using WeatherKit,
|
|
157
|
+
not a design choice. Fetch it from the service:
|
|
209
158
|
|
|
210
159
|
```swift
|
|
211
|
-
|
|
212
|
-
return try await weatherService.attribution
|
|
213
|
-
}
|
|
160
|
+
let credit = try await forecaster.attribution
|
|
214
161
|
```
|
|
215
162
|
|
|
216
|
-
|
|
163
|
+
Pick the mark that matches the color scheme and link to the legal page:
|
|
217
164
|
|
|
218
165
|
```swift
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
struct WeatherAttributionView: View {
|
|
223
|
-
let attribution: WeatherAttribution
|
|
224
|
-
@Environment(\.colorScheme) private var colorScheme
|
|
166
|
+
struct WeatherCredit: View {
|
|
167
|
+
let credit: WeatherAttribution
|
|
168
|
+
@Environment(\.colorScheme) private var scheme
|
|
225
169
|
|
|
226
170
|
var body: some View {
|
|
227
|
-
VStack {
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
image
|
|
231
|
-
.resizable()
|
|
232
|
-
.scaledToFit()
|
|
233
|
-
.frame(height: 20)
|
|
171
|
+
VStack(spacing: 6) {
|
|
172
|
+
AsyncImage(url: scheme == .dark ? credit.combinedMarkDarkURL : credit.combinedMarkLightURL) { mark in
|
|
173
|
+
mark.resizable().scaledToFit()
|
|
234
174
|
} placeholder: {
|
|
235
|
-
|
|
175
|
+
Text(credit.serviceName).font(.caption2)
|
|
236
176
|
}
|
|
177
|
+
.frame(height: 14)
|
|
237
178
|
|
|
238
|
-
|
|
239
|
-
Link("Weather data sources", destination: attribution.legalPageURL)
|
|
179
|
+
Link("Other data sources", destination: credit.legalPageURL)
|
|
240
180
|
.font(.caption2)
|
|
241
|
-
.foregroundStyle(.secondary)
|
|
242
181
|
}
|
|
243
182
|
}
|
|
244
|
-
|
|
245
|
-
private var markURL: URL {
|
|
246
|
-
colorScheme == .dark
|
|
247
|
-
? attribution.combinedMarkDarkURL
|
|
248
|
-
: attribution.combinedMarkLightURL
|
|
249
|
-
}
|
|
250
183
|
}
|
|
251
184
|
```
|
|
252
185
|
|
|
253
|
-
|
|
186
|
+
`WeatherAttribution` provides:
|
|
254
187
|
|
|
255
188
|
| Property | Use |
|
|
256
|
-
|
|
257
|
-
| `combinedMarkLightURL` |
|
|
258
|
-
| `combinedMarkDarkURL` |
|
|
259
|
-
| `squareMarkURL` |
|
|
260
|
-
| `legalPageURL` |
|
|
261
|
-
| `legalAttributionText` |
|
|
262
|
-
| `serviceName` |
|
|
189
|
+
| --- | --- |
|
|
190
|
+
| `combinedMarkLightURL` | Mark for light backgrounds |
|
|
191
|
+
| `combinedMarkDarkURL` | Mark for dark backgrounds |
|
|
192
|
+
| `squareMarkURL` | Compact square mark |
|
|
193
|
+
| `legalPageURL` | Page listing data sources; link to it |
|
|
194
|
+
| `legalAttributionText` | Plain-text alternative when showing a web page is not practical |
|
|
195
|
+
| `serviceName` | The provider name, "Apple Weather" |
|
|
263
196
|
|
|
264
197
|
## Availability
|
|
265
198
|
|
|
266
|
-
|
|
267
|
-
|
|
199
|
+
Minute forecasts and alerts are not offered in every country. Ask before
|
|
200
|
+
building UI around them:
|
|
268
201
|
|
|
269
202
|
```swift
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
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
|
-
}
|
|
203
|
+
let coverage = try await forecaster.weather(for: site, including: .availability)
|
|
204
|
+
let offersAlerts = coverage.alertAvailability == .available
|
|
205
|
+
let offersNextHour = coverage.minuteAvailability == .available
|
|
305
206
|
```
|
|
306
207
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
Each dataset query counts against your API quota. Fetch only what you display.
|
|
208
|
+
Each is a `WeatherAvailability.AvailabilityKind`: `.available`,
|
|
209
|
+
`.temporarilyUnavailable`, `.unsupported` or `.unknown`.
|
|
310
210
|
|
|
311
|
-
|
|
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
|
-
```
|
|
211
|
+
## Common mistakes
|
|
323
212
|
|
|
324
|
-
|
|
213
|
+
1. **No attribution.** Leaving it out breaks the WeatherKit terms and is a
|
|
214
|
+
reason for App Review to reject the app.
|
|
215
|
+
2. **Fetching everything to show one number.** `weather(for:)` returns every
|
|
216
|
+
dataset and each one counts against the quota. Use
|
|
217
|
+
`weather(for:including: .current)` when only current conditions appear.
|
|
218
|
+
3. **Force-unwrapping the minute forecast.** It is `nil` in unsupported
|
|
219
|
+
regions and the app crashes there. Use `if let`.
|
|
220
|
+
4. **Missing capability.** Without the capability and the portal switch,
|
|
221
|
+
`WeatherService` calls throw at runtime.
|
|
222
|
+
5. **Refetching on every appearance.** Weather does not change second to
|
|
223
|
+
second. Cache results with a staleness window, for example an actor that
|
|
224
|
+
keeps entries for 600 seconds (see the reference file).
|
|
325
225
|
|
|
326
|
-
|
|
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
|
-
}
|
|
382
|
-
```
|
|
226
|
+
## Review checklist
|
|
383
227
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
- [ ]
|
|
387
|
-
- [ ]
|
|
388
|
-
- [ ]
|
|
389
|
-
- [ ]
|
|
390
|
-
- [ ]
|
|
391
|
-
- [ ]
|
|
392
|
-
- [ ]
|
|
393
|
-
- [ ]
|
|
394
|
-
- [ ]
|
|
395
|
-
- [ ] `
|
|
396
|
-
- [ ] Location permission requested before passing `CLLocation` to service
|
|
397
|
-
- [ ] Temperature and measurements formatted with `Measurement.formatted()` for locale
|
|
228
|
+
- [ ] WeatherKit capability added in Xcode and enabled in the portal
|
|
229
|
+
- [ ] Active developer program membership
|
|
230
|
+
- [ ] Attribution visible wherever weather data appears
|
|
231
|
+
- [ ] Attribution mark follows light and dark mode
|
|
232
|
+
- [ ] Legal page linked, or `legalAttributionText` shown
|
|
233
|
+
- [ ] Only the datasets the screen needs are requested
|
|
234
|
+
- [ ] Minute forecast treated as optional
|
|
235
|
+
- [ ] Alerts nil-checked
|
|
236
|
+
- [ ] Responses cached for 5 to 15 minutes
|
|
237
|
+
- [ ] `WeatherAvailability` checked before region-limited datasets
|
|
238
|
+
- [ ] Location permission granted before a device `CLLocation` is passed in
|
|
239
|
+
- [ ] Measurements displayed with `formatted()` so units follow the locale
|
|
398
240
|
|
|
399
241
|
## References
|
|
400
242
|
|
|
401
|
-
-
|
|
402
|
-
- [WeatherKit
|
|
403
|
-
- [WeatherService](https://
|
|
404
|
-
- [WeatherAttribution](https://
|
|
405
|
-
- [WeatherQuery](https://
|
|
406
|
-
- [CurrentWeather](https://
|
|
407
|
-
- [Forecast](https://
|
|
408
|
-
- [HourWeather](https://
|
|
409
|
-
- [DayWeather](https://
|
|
410
|
-
- [WeatherAlert](https://
|
|
411
|
-
- [WeatherAvailability](https://
|
|
412
|
-
- [Fetching weather forecasts with WeatherKit](https://
|
|
243
|
+
- [references/weatherkit-patterns.md](references/weatherkit-patterns.md)
|
|
244
|
+
- [WeatherKit](https://developer.apple.com/documentation/weatherkit)
|
|
245
|
+
- [WeatherService](https://developer.apple.com/documentation/weatherkit/weatherservice)
|
|
246
|
+
- [WeatherAttribution](https://developer.apple.com/documentation/weatherkit/weatherattribution)
|
|
247
|
+
- [WeatherQuery](https://developer.apple.com/documentation/weatherkit/weatherquery)
|
|
248
|
+
- [CurrentWeather](https://developer.apple.com/documentation/weatherkit/currentweather)
|
|
249
|
+
- [Forecast](https://developer.apple.com/documentation/weatherkit/forecast)
|
|
250
|
+
- [HourWeather](https://developer.apple.com/documentation/weatherkit/hourweather)
|
|
251
|
+
- [DayWeather](https://developer.apple.com/documentation/weatherkit/dayweather)
|
|
252
|
+
- [WeatherAlert](https://developer.apple.com/documentation/weatherkit/weatheralert)
|
|
253
|
+
- [WeatherAvailability](https://developer.apple.com/documentation/weatherkit/weatheravailability)
|
|
254
|
+
- [Fetching weather forecasts with WeatherKit](https://developer.apple.com/documentation/weatherkit/fetching_weather_forecasts_with_weatherkit)
|