@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
|
@@ -1,500 +1,308 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: realitykit-ar
|
|
3
|
-
description: "
|
|
3
|
+
description: "RealityKit and ARKit on iOS: RealityView camera content, AR camera availability and permission, entities and components, USDZ loading, plane and world anchoring, entity hit tests versus ARKit raycasts, entity gestures, per-frame scene updates, world tracking, physics, materials, performance. Use when building iOS AR or 3D experiences."
|
|
4
4
|
metadata:
|
|
5
|
-
source:
|
|
5
|
+
source: multi-agent-pipeline
|
|
6
6
|
---
|
|
7
|
-
# RealityKit
|
|
8
|
-
Build AR experiences on iOS using RealityKit for rendering and ARKit for world
|
|
9
|
-
tracking. Covers `RealityView`, entity management, raycasting, scene
|
|
10
|
-
understanding, and gesture-based interactions. Targets Swift 6.3 / iOS 26+.
|
|
11
|
-
|
|
12
|
-
## Contents
|
|
13
|
-
|
|
14
|
-
- [Setup](#setup)
|
|
15
|
-
- [RealityView Basics](#realityview-basics)
|
|
16
|
-
- [Loading and Creating Entities](#loading-and-creating-entities)
|
|
17
|
-
- [Anchoring and Placement](#anchoring-and-placement)
|
|
18
|
-
- [Raycasting](#raycasting)
|
|
19
|
-
- [Gestures and Interaction](#gestures-and-interaction)
|
|
20
|
-
- [Scene Understanding](#scene-understanding)
|
|
21
|
-
- [Common Mistakes](#common-mistakes)
|
|
22
|
-
- [Review Checklist](#review-checklist)
|
|
23
|
-
- [References](#references)
|
|
24
7
|
|
|
25
|
-
|
|
8
|
+
# RealityKit and ARKit on iOS
|
|
26
9
|
|
|
27
|
-
|
|
10
|
+
RealityKit draws the 3D content; ARKit tracks the device in the room. Code here
|
|
11
|
+
targets Swift 6.3 and iOS 26 or later.
|
|
28
12
|
|
|
29
|
-
|
|
30
|
-
2. On iOS, `RealityViewCameraContent` displays an AR camera view by default (iOS 18+, macOS 15+); use `.virtual` camera mode for explicit non-AR fallback
|
|
31
|
-
3. No entitlement is required for basic AR. If AR is core to the app, add the `arkit` required-device capability; otherwise gate AR UI with `isSupported`.
|
|
13
|
+
## Setup
|
|
32
14
|
|
|
33
|
-
###
|
|
15
|
+
### Project configuration
|
|
34
16
|
|
|
35
|
-
|
|
36
|
-
`
|
|
17
|
+
- Info.plist needs `NSCameraUsageDescription`.
|
|
18
|
+
- On iOS, `RealityViewCameraContent` (iOS 18+, macOS 15+) shows the AR camera
|
|
19
|
+
feed by default. Switch to the `.virtual` camera when you want a plain 3D
|
|
20
|
+
view without AR.
|
|
21
|
+
- Basic AR needs no entitlement.
|
|
22
|
+
- If the app is useless without AR, list `arkit` under
|
|
23
|
+
`UIRequiredDeviceCapabilities`. Otherwise keep the app installable everywhere
|
|
24
|
+
and hide AR features at runtime with `isSupported`.
|
|
37
25
|
|
|
38
|
-
|
|
39
|
-
import ARKit
|
|
26
|
+
### Device support
|
|
40
27
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
return
|
|
44
|
-
}
|
|
45
|
-
```
|
|
28
|
+
World tracking needs an A9 chip or newer. Check
|
|
29
|
+
`ARWorldTrackingConfiguration.isSupported` every time before presenting AR UI.
|
|
46
30
|
|
|
47
|
-
###
|
|
31
|
+
### Main types
|
|
48
32
|
|
|
49
|
-
| Type |
|
|
50
|
-
|
|
51
|
-
| `RealityView` | iOS 18+, visionOS 1+ |
|
|
52
|
-
| `RealityViewCameraContent` | iOS 18+, macOS 15+ |
|
|
53
|
-
| `Entity` |
|
|
54
|
-
| `ModelEntity` |
|
|
55
|
-
| `AnchorEntity` |
|
|
33
|
+
| Type | Availability | Role |
|
|
34
|
+
| --- | --- | --- |
|
|
35
|
+
| `RealityView` | iOS 18+, visionOS 1+ | Embeds a RealityKit scene in SwiftUI |
|
|
36
|
+
| `RealityViewCameraContent` | iOS 18+, macOS 15+ | Camera-backed content: AR on iOS, plain 3D on macOS |
|
|
37
|
+
| `Entity` | | Base class for everything in a scene |
|
|
38
|
+
| `ModelEntity` | | Entity that renders a mesh |
|
|
39
|
+
| `AnchorEntity` | | Ties children to something in the real world |
|
|
56
40
|
|
|
57
|
-
## RealityView
|
|
58
|
-
|
|
59
|
-
`RealityView` is the SwiftUI entry point for RealityKit.
|
|
60
|
-
`RealityViewCameraContent` is the iOS/macOS content type. On iOS, it uses an AR
|
|
61
|
-
camera view by default and can use `content.camera = .virtual` for non-AR mode
|
|
62
|
-
when requested or when AR/camera access is unavailable.
|
|
41
|
+
## RealityView basics
|
|
63
42
|
|
|
64
43
|
```swift
|
|
65
44
|
import ARKit
|
|
66
|
-
import SwiftUI
|
|
67
45
|
import RealityKit
|
|
46
|
+
import SwiftUI
|
|
68
47
|
|
|
69
|
-
struct
|
|
48
|
+
struct MarbleView: View {
|
|
70
49
|
var body: some View {
|
|
71
|
-
RealityView { (
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
mesh: .generateSphere(radius: 0.05),
|
|
78
|
-
materials: [SimpleMaterial(
|
|
79
|
-
color: .blue,
|
|
80
|
-
isMetallic: true
|
|
81
|
-
)]
|
|
50
|
+
RealityView { (scene: inout RealityViewCameraContent) in
|
|
51
|
+
let tracks = ARWorldTrackingConfiguration.isSupported
|
|
52
|
+
if tracks == false { scene.camera = .virtual }
|
|
53
|
+
let marble = ModelEntity(
|
|
54
|
+
mesh: .generateSphere(radius: 0.04),
|
|
55
|
+
materials: [SimpleMaterial(color: .systemTeal, isMetallic: true)]
|
|
82
56
|
)
|
|
83
|
-
|
|
84
|
-
|
|
57
|
+
marble.position = SIMD3(x: 0, y: 0, z: -0.5)
|
|
58
|
+
scene.add(marble)
|
|
85
59
|
}
|
|
86
60
|
}
|
|
87
61
|
}
|
|
88
62
|
```
|
|
89
63
|
|
|
90
|
-
|
|
64
|
+
Distances are in meters, so `-0.5` on z puts the marble half a meter in front
|
|
65
|
+
of the camera. Use `.virtual` whenever the user asks for a non-AR view, or when
|
|
66
|
+
world tracking or the camera is unavailable.
|
|
91
67
|
|
|
92
|
-
|
|
68
|
+
### Make, then update
|
|
69
|
+
|
|
70
|
+
The first closure builds the scene once. The `update:` closure runs when SwiftUI
|
|
71
|
+
state it reads changes, so it only adjusts what already exists.
|
|
93
72
|
|
|
94
73
|
```swift
|
|
95
|
-
struct
|
|
96
|
-
|
|
74
|
+
struct TintedMarble: View {
|
|
75
|
+
var tint: UIColor
|
|
97
76
|
|
|
98
77
|
var body: some View {
|
|
99
|
-
RealityView {
|
|
100
|
-
let
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
)
|
|
107
|
-
box.name = "colorBox"
|
|
108
|
-
box.position = [0, 0, -0.5]
|
|
109
|
-
content.add(box)
|
|
110
|
-
} update: { content in
|
|
111
|
-
if let box = content.entities.first(
|
|
112
|
-
where: { $0.name == "colorBox" }
|
|
113
|
-
) as? ModelEntity {
|
|
114
|
-
box.model?.materials = [SimpleMaterial(
|
|
115
|
-
color: modelColor,
|
|
116
|
-
isMetallic: false
|
|
117
|
-
)]
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
Button("Change Color") {
|
|
122
|
-
modelColor = modelColor == .red ? .green : .red
|
|
78
|
+
RealityView { scene in
|
|
79
|
+
let marble = ModelEntity(mesh: .generateSphere(radius: 0.04))
|
|
80
|
+
marble.name = "marble"
|
|
81
|
+
scene.add(marble)
|
|
82
|
+
} update: { scene in
|
|
83
|
+
let marble = scene.entities.first { $0.name == "marble" } as? ModelEntity
|
|
84
|
+
marble?.model?.materials = [SimpleMaterial(color: tint, isMetallic: false)]
|
|
123
85
|
}
|
|
124
86
|
}
|
|
125
87
|
}
|
|
126
88
|
```
|
|
127
89
|
|
|
128
|
-
## Loading and
|
|
90
|
+
## Loading and composing entities
|
|
129
91
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
Load 3D models asynchronously to avoid blocking the main thread:
|
|
92
|
+
Load USDZ files asynchronously inside the make closure, which is already
|
|
93
|
+
`async`:
|
|
133
94
|
|
|
134
95
|
```swift
|
|
135
96
|
RealityView { content in
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
}
|
|
97
|
+
guard let lamp = try? await ModelEntity(named: "desk_lamp") else { return }
|
|
98
|
+
lamp.scale = SIMD3(repeating: 0.01)
|
|
99
|
+
lamp.position = SIMD3(x: 0, y: -0.2, z: -0.8)
|
|
100
|
+
content.add(lamp)
|
|
141
101
|
}
|
|
142
102
|
```
|
|
143
103
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
Entities use an ECS (Entity Component System) architecture. Add components
|
|
147
|
-
to give entities behavior:
|
|
104
|
+
Behaviour comes from components (entity component system), attached with
|
|
105
|
+
`entity.components.set(...)`:
|
|
148
106
|
|
|
149
107
|
```swift
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
)
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
box.components.set(PhysicsBodyComponent(
|
|
157
|
-
massProperties: .default,
|
|
158
|
-
material: .default,
|
|
159
|
-
mode: .dynamic
|
|
160
|
-
))
|
|
161
|
-
|
|
162
|
-
// Add collision shape for interaction
|
|
163
|
-
box.components.set(CollisionComponent(
|
|
164
|
-
shapes: [.generateBox(size: [0.1, 0.1, 0.1])]
|
|
165
|
-
))
|
|
166
|
-
|
|
167
|
-
// Enable input targeting for gestures
|
|
168
|
-
box.components.set(InputTargetComponent())
|
|
108
|
+
@MainActor
|
|
109
|
+
func makeThrowable(_ crate: ModelEntity) {
|
|
110
|
+
let body = PhysicsBodyComponent(massProperties: .default, material: .default, mode: .dynamic)
|
|
111
|
+
let shape = CollisionComponent(shapes: [.generateBox(size: SIMD3(repeating: 0.1))])
|
|
112
|
+
crate.components.set([body, shape, InputTargetComponent()])
|
|
113
|
+
}
|
|
169
114
|
```
|
|
170
115
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
116
|
+
- `PhysicsBodyComponent` puts the entity in the physics simulation.
|
|
117
|
+
- `CollisionComponent` gives it a shape for collisions and for picking.
|
|
118
|
+
- `InputTargetComponent` lets gestures target it.
|
|
174
119
|
|
|
175
|
-
|
|
120
|
+
## Anchoring and placement
|
|
176
121
|
|
|
177
122
|
```swift
|
|
178
123
|
RealityView { content in
|
|
179
|
-
|
|
180
|
-
let
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
minimumBounds: [0.2, 0.2]
|
|
184
|
-
))
|
|
185
|
-
|
|
186
|
-
let model = ModelEntity(
|
|
187
|
-
mesh: .generateBox(size: 0.1),
|
|
188
|
-
materials: [SimpleMaterial(color: .orange, isMetallic: false)]
|
|
189
|
-
)
|
|
190
|
-
floorAnchor.addChild(model)
|
|
191
|
-
content.add(floorAnchor)
|
|
124
|
+
let floorSpot = SIMD2<Float>(0.2, 0.2)
|
|
125
|
+
let rug = AnchorEntity(.plane(.horizontal, classification: .floor, minimumBounds: floorSpot))
|
|
126
|
+
rug.addChild(ModelEntity(mesh: .generatePlane(width: 0.5, depth: 0.3)))
|
|
127
|
+
content.add(rug)
|
|
192
128
|
}
|
|
193
129
|
```
|
|
194
130
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
|
198
|
-
|
|
199
|
-
| `.plane(.
|
|
200
|
-
| `.
|
|
201
|
-
| `.plane(.any, ...)` | Any detected plane |
|
|
202
|
-
| `.world(transform:)` | Fixed world-space position |
|
|
131
|
+
| Target | Use for |
|
|
132
|
+
| --- | --- |
|
|
133
|
+
| `.plane(.horizontal, ...)` | Floors, tables |
|
|
134
|
+
| `.plane(.vertical, ...)` | Walls |
|
|
135
|
+
| `.plane(.any, ...)` | Whatever plane is found first |
|
|
136
|
+
| `.world(transform:)` | A fixed position in world space |
|
|
203
137
|
|
|
204
|
-
## Raycasting
|
|
138
|
+
## Raycasting: three different questions
|
|
205
139
|
|
|
206
|
-
|
|
140
|
+
Scene queries and real-world raycasts answer different questions. Keep them
|
|
141
|
+
apart.
|
|
207
142
|
|
|
208
|
-
- `RealityViewCameraContent.ray(through:in:to:)`
|
|
209
|
-
RealityKit
|
|
210
|
-
|
|
211
|
-
- `
|
|
212
|
-
entities
|
|
213
|
-
|
|
214
|
-
-
|
|
215
|
-
-
|
|
216
|
-
|
|
217
|
-
`AnchorEntity(raycastResult:)`.
|
|
143
|
+
- `RealityViewCameraContent.ray(through:in:to:)` turns a screen point into a
|
|
144
|
+
ray in RealityKit coordinates. It points into the virtual scene and proves
|
|
145
|
+
nothing about real-world geometry.
|
|
146
|
+
- The content's `hitTest(point:in:query:mask:)` method finds virtual
|
|
147
|
+
entities that carry `CollisionComponent` shapes. Use it to pick entities and
|
|
148
|
+
target gestures, never to find planes.
|
|
149
|
+
- For simple placement on a detected plane, use `AnchorEntity(.plane(...))`.
|
|
150
|
+
- To intersect a real surface once, build an ARKit `ARRaycastQuery`, run it
|
|
151
|
+
with `ARSession.raycast(_:)`, and anchor with `AnchorEntity(raycastResult:)`.
|
|
218
152
|
|
|
219
153
|
```swift
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
let
|
|
223
|
-
anchor
|
|
154
|
+
@MainActor
|
|
155
|
+
func placeOnSurface(_ item: Entity, query: ARRaycastQuery, session: ARSession, into content: RealityViewCameraContent) {
|
|
156
|
+
guard let hit = session.raycast(query).first else { return }
|
|
157
|
+
let anchor = AnchorEntity(raycastResult: hit)
|
|
158
|
+
anchor.addChild(item)
|
|
224
159
|
content.add(anchor)
|
|
225
160
|
}
|
|
226
161
|
```
|
|
227
162
|
|
|
228
|
-
|
|
163
|
+
An entity hit test is never a stand-in for an ARKit surface raycast.
|
|
229
164
|
|
|
230
|
-
## Gestures and
|
|
165
|
+
## Gestures and interaction
|
|
231
166
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
167
|
+
Entity gestures need two components: `CollisionComponent` so there is a shape
|
|
168
|
+
to hit, and `InputTargetComponent` so input is routed to it. Collision shapes
|
|
169
|
+
make an entity hittable by `hitTest`, `SpatialTapGesture` and
|
|
170
|
+
`targetedToAnyEntity()`; this is virtual picking, not surface detection.
|
|
171
|
+
`AccessibilityComponent` carries an entity's label and actions. How SwiftUI gestures
|
|
172
|
+
combine, and the policy for VoiceOver or Switch Control, belong to the gesture
|
|
173
|
+
and accessibility skills.
|
|
236
174
|
|
|
237
|
-
|
|
175
|
+
The iOS SDK has neither `location3D` on a drag value nor
|
|
176
|
+
`convert(_:from:to:)` on the targeted value; those are visionOS API. Map the 2D location into the parent
|
|
177
|
+
entity's space with `unproject(_:to:)` (iOS 18+), which returns `nil` when the
|
|
178
|
+
point cannot be mapped.
|
|
238
179
|
|
|
239
180
|
```swift
|
|
240
|
-
struct
|
|
181
|
+
struct DraggableScene: View {
|
|
241
182
|
var body: some View {
|
|
242
183
|
RealityView { content in
|
|
243
|
-
let
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
box.components.set(CollisionComponent(
|
|
249
|
-
shapes: [.generateBox(size: [0.1, 0.1, 0.1])]
|
|
250
|
-
))
|
|
251
|
-
box.components.set(InputTargetComponent())
|
|
252
|
-
box.name = "draggable"
|
|
253
|
-
content.add(box)
|
|
184
|
+
let puck = ModelEntity(mesh: .generateCylinder(height: 0.02, radius: 0.05))
|
|
185
|
+
puck.generateCollisionShapes(recursive: false)
|
|
186
|
+
puck.components.set(InputTargetComponent())
|
|
187
|
+
puck.position = [0, 0, -0.6]
|
|
188
|
+
content.add(puck)
|
|
254
189
|
}
|
|
255
190
|
.gesture(
|
|
256
191
|
DragGesture()
|
|
257
192
|
.targetedToAnyEntity()
|
|
258
|
-
.onChanged {
|
|
259
|
-
let
|
|
260
|
-
|
|
261
|
-
entity.position =
|
|
262
|
-
value.location3D,
|
|
263
|
-
from: .local,
|
|
264
|
-
to: parent
|
|
265
|
-
)
|
|
193
|
+
.onChanged { drag in
|
|
194
|
+
guard let parent = drag.entity.parent,
|
|
195
|
+
let point = drag.unproject(\.location, to: parent) else { return }
|
|
196
|
+
drag.entity.position = point
|
|
266
197
|
}
|
|
267
198
|
)
|
|
268
199
|
}
|
|
269
200
|
}
|
|
270
201
|
```
|
|
271
202
|
|
|
272
|
-
|
|
273
|
-
hittable by `RealityViewCameraContent.hitTest`, `SpatialTapGesture`, or
|
|
274
|
-
`targetedToAnyEntity()`. Pair it with `InputTargetComponent`; this enables
|
|
275
|
-
virtual entity picking, not ARKit surface detection.
|
|
276
|
-
|
|
277
|
-
## Scene Understanding
|
|
278
|
-
|
|
279
|
-
### Per-Frame Updates
|
|
280
|
-
|
|
281
|
-
Subscribe to scene update events for continuous processing:
|
|
282
|
-
|
|
283
|
-
```swift
|
|
284
|
-
RealityView { content in
|
|
285
|
-
let entity = ModelEntity(
|
|
286
|
-
mesh: .generateSphere(radius: 0.05),
|
|
287
|
-
materials: [SimpleMaterial(color: .yellow, isMetallic: false)]
|
|
288
|
-
)
|
|
289
|
-
entity.position = [0, 0, -0.5]
|
|
290
|
-
content.add(entity)
|
|
291
|
-
|
|
292
|
-
_ = content.subscribe(to: SceneEvents.Update.self) { event in
|
|
293
|
-
let time = Float(event.deltaTime)
|
|
294
|
-
entity.position.y += sin(Float(Date().timeIntervalSince1970)) * time * 0.1
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
```
|
|
298
|
-
|
|
299
|
-
### Platform Boundaries
|
|
300
|
-
|
|
301
|
-
On visionOS, ARKit provides a different API surface with `ARKitSession`,
|
|
302
|
-
`WorldTrackingProvider`, and `PlaneDetectionProvider`. These visionOS-specific
|
|
303
|
-
types are not available on iOS. On iOS, RealityKit handles world tracking
|
|
304
|
-
automatically through `RealityViewCameraContent`.
|
|
305
|
-
|
|
306
|
-
For iOS architecture or migration notes, explicitly name the iOS RealityKit path and handoffs:
|
|
307
|
-
|
|
308
|
-
- Gate AR with `ARWorldTrackingConfiguration.isSupported`.
|
|
309
|
-
- Host content with `RealityViewCameraContent`.
|
|
310
|
-
- Build scenes from `Entity`/`ModelEntity` and place with `AnchorEntity`.
|
|
311
|
-
- Include a compact `Handoffs` line in architecture/review notes:
|
|
312
|
-
`CollisionComponent` + `InputTargetComponent` handle RealityKit interaction;
|
|
313
|
-
`AccessibilityComponent` handles RealityKit entity accessibility metadata;
|
|
314
|
-
detailed SwiftUI gestures and VoiceOver/Switch Control policy belong to siblings.
|
|
315
|
-
|
|
316
|
-
Treat existing `SCNView`/`SCNNode` work as either a separate SceneKit path or an
|
|
317
|
-
explicit migration to RealityKit, not a mixed scene graph.
|
|
318
|
-
|
|
319
|
-
## Common Mistakes
|
|
320
|
-
|
|
321
|
-
### DON'T: Skip AR capability checks
|
|
322
|
-
|
|
323
|
-
Not all devices support AR. Showing a black camera view with no feedback
|
|
324
|
-
confuses users.
|
|
325
|
-
|
|
326
|
-
```swift
|
|
327
|
-
// WRONG -- no device check
|
|
328
|
-
struct MyARView: View {
|
|
329
|
-
var body: some View {
|
|
330
|
-
RealityView { content in
|
|
331
|
-
// Fails silently on unsupported devices
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
// CORRECT -- check support and show fallback
|
|
337
|
-
struct MyARView: View {
|
|
338
|
-
var body: some View {
|
|
339
|
-
if ARWorldTrackingConfiguration.isSupported {
|
|
340
|
-
RealityView { content in
|
|
341
|
-
// AR content
|
|
342
|
-
}
|
|
343
|
-
} else {
|
|
344
|
-
ContentUnavailableView(
|
|
345
|
-
"AR Not Supported",
|
|
346
|
-
systemImage: "arkit",
|
|
347
|
-
description: Text("This device does not support AR.")
|
|
348
|
-
)
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
```
|
|
353
|
-
|
|
354
|
-
### DON'T: Load heavy models synchronously
|
|
355
|
-
|
|
356
|
-
Loading large USDZ files on the main thread causes frame drops and hangs.
|
|
357
|
-
The `make` closure of `RealityView` is `async` -- use it.
|
|
358
|
-
|
|
359
|
-
```swift
|
|
360
|
-
// WRONG -- synchronous load blocks the main thread
|
|
361
|
-
RealityView { content in
|
|
362
|
-
let model = try! Entity.load(named: "large-scene")
|
|
363
|
-
content.add(model)
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
// CORRECT -- async load
|
|
367
|
-
RealityView { content in
|
|
368
|
-
if let model = try? await ModelEntity(named: "large-scene") {
|
|
369
|
-
content.add(model)
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
```
|
|
373
|
-
|
|
374
|
-
### DON'T: Forget collision and input target components for interactive entities
|
|
375
|
-
|
|
376
|
-
Gestures only work on entities that have both `CollisionComponent` and
|
|
377
|
-
`InputTargetComponent`. Without them, taps and drags pass through.
|
|
378
|
-
|
|
379
|
-
```swift
|
|
380
|
-
// WRONG -- entity ignores gestures
|
|
381
|
-
let box = ModelEntity(mesh: .generateBox(size: 0.1))
|
|
382
|
-
content.add(box)
|
|
383
|
-
|
|
384
|
-
// CORRECT -- add collision and input components
|
|
385
|
-
let box = ModelEntity(
|
|
386
|
-
mesh: .generateBox(size: 0.1),
|
|
387
|
-
materials: [SimpleMaterial(color: .red, isMetallic: false)]
|
|
388
|
-
)
|
|
389
|
-
box.components.set(CollisionComponent(
|
|
390
|
-
shapes: [.generateBox(size: [0.1, 0.1, 0.1])]
|
|
391
|
-
))
|
|
392
|
-
box.components.set(InputTargetComponent())
|
|
393
|
-
content.add(box)
|
|
394
|
-
```
|
|
395
|
-
|
|
396
|
-
### DON'T: Create new entities in the update closure
|
|
397
|
-
|
|
398
|
-
The `update` closure runs on every SwiftUI state change. Creating entities
|
|
399
|
-
there duplicates content on each render pass.
|
|
400
|
-
|
|
401
|
-
```swift
|
|
402
|
-
// WRONG -- duplicates entities on every state change
|
|
403
|
-
RealityView { content in
|
|
404
|
-
// empty
|
|
405
|
-
} update: { content in
|
|
406
|
-
let sphere = ModelEntity(mesh: .generateSphere(radius: 0.05))
|
|
407
|
-
content.add(sphere) // Added again on every update
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
// CORRECT -- create in make, modify in update
|
|
411
|
-
RealityView { content in
|
|
412
|
-
let sphere = ModelEntity(mesh: .generateSphere(radius: 0.05))
|
|
413
|
-
sphere.name = "mySphere"
|
|
414
|
-
content.add(sphere)
|
|
415
|
-
} update: { content in
|
|
416
|
-
if let sphere = content.entities.first(
|
|
417
|
-
where: { $0.name == "mySphere" }
|
|
418
|
-
) as? ModelEntity {
|
|
419
|
-
// Modify existing entity
|
|
420
|
-
sphere.position.y = newYPosition
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
```
|
|
424
|
-
|
|
425
|
-
### DON'T: Ignore camera permission
|
|
203
|
+
## Scene updates and platform boundaries
|
|
426
204
|
|
|
427
|
-
|
|
428
|
-
view shows a black screen with no explanation.
|
|
205
|
+
### Per-frame work
|
|
429
206
|
|
|
430
207
|
```swift
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
struct ARContainerView: View {
|
|
438
|
-
@State private var cameraAuthorized = false
|
|
439
|
-
|
|
440
|
-
var body: some View {
|
|
441
|
-
Group {
|
|
442
|
-
if cameraAuthorized {
|
|
443
|
-
RealityView { content in
|
|
444
|
-
// AR content
|
|
445
|
-
}
|
|
446
|
-
} else {
|
|
447
|
-
ContentUnavailableView(
|
|
448
|
-
"Camera Access Required",
|
|
449
|
-
systemImage: "camera.fill",
|
|
450
|
-
description: Text("Enable camera in Settings to use AR.")
|
|
451
|
-
)
|
|
452
|
-
}
|
|
453
|
-
}
|
|
454
|
-
.task {
|
|
455
|
-
let status = AVCaptureDevice.authorizationStatus(for: .video)
|
|
456
|
-
if status == .authorized {
|
|
457
|
-
cameraAuthorized = true
|
|
458
|
-
} else if status == .notDetermined {
|
|
459
|
-
cameraAuthorized = await AVCaptureDevice
|
|
460
|
-
.requestAccess(for: .video)
|
|
461
|
-
}
|
|
462
|
-
}
|
|
208
|
+
RealityView { scene in
|
|
209
|
+
let spinner = ModelEntity(mesh: .generateBox(size: 0.08))
|
|
210
|
+
scene.add(spinner)
|
|
211
|
+
_ = scene.subscribe(to: SceneEvents.Update.self) { frame in
|
|
212
|
+
let step = Float(frame.deltaTime)
|
|
213
|
+
spinner.orientation *= simd_quatf(angle: step, axis: [0, 1, 0])
|
|
463
214
|
}
|
|
464
215
|
}
|
|
465
216
|
```
|
|
466
217
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
-
|
|
473
|
-
|
|
474
|
-
-
|
|
475
|
-
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
-
|
|
218
|
+
Scale motion by `deltaTime`. `subscribe` hands back an `EventSubscription`;
|
|
219
|
+
store it when you plan to cancel it later, or drop it with `_ =` as here.
|
|
220
|
+
|
|
221
|
+
### What belongs to which platform
|
|
222
|
+
|
|
223
|
+
- visionOS drives ARKit through `ARKitSession`, `WorldTrackingProvider` and
|
|
224
|
+
`PlaneDetectionProvider`. None of these exist on iOS.
|
|
225
|
+
- On iOS, `RealityViewCameraContent` runs world tracking for you.
|
|
226
|
+
- An iOS design note should say: gate on `ARWorldTrackingConfiguration.isSupported`,
|
|
227
|
+
host in `RealityViewCameraContent`, build from `Entity` and `ModelEntity`,
|
|
228
|
+
place with `AnchorEntity`.
|
|
229
|
+
- Close architecture and review notes with a short **Handoffs** line:
|
|
230
|
+
`CollisionComponent` plus `InputTargetComponent` for interaction,
|
|
231
|
+
`AccessibilityComponent` for entity accessibility metadata, and detailed
|
|
232
|
+
gestures and VoiceOver or Switch Control policy sent to the sibling skills.
|
|
233
|
+
- Existing `SCNView` or `SCNNode` code stays a separate SceneKit path or gets an
|
|
234
|
+
explicit migration to RealityKit. Never mix the two scene graphs.
|
|
235
|
+
|
|
236
|
+
## Common mistakes
|
|
237
|
+
|
|
238
|
+
- **No capability check.** Unsupported devices just show black where the
|
|
239
|
+
camera should be, and nothing says why.
|
|
240
|
+
|
|
241
|
+
```swift
|
|
242
|
+
if ARWorldTrackingConfiguration.isSupported {
|
|
243
|
+
MarbleView()
|
|
244
|
+
} else {
|
|
245
|
+
ContentUnavailableView("AR unavailable", systemImage: "arkit",
|
|
246
|
+
description: Text("Room tracking needs newer hardware."))
|
|
247
|
+
}
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
- **Blocking loads.** Loading with the synchronous `Entity.load(named:)` (often
|
|
251
|
+
written with a forced `try`) on the main thread drops frames or hangs. The
|
|
252
|
+
make closure is `async`; use `try? await ModelEntity(named:)`.
|
|
253
|
+
- **Missing components.** Without both `CollisionComponent` and
|
|
254
|
+
`InputTargetComponent`, taps and drags go straight through the entity.
|
|
255
|
+
- **Building in `update`.** SwiftUI calls update again whenever state it reads
|
|
256
|
+
changes, so creating entities there duplicates them. Create in make, name them,
|
|
257
|
+
and look them up in update.
|
|
258
|
+
- **Ignoring camera permission.** A denied camera also gives a black screen.
|
|
259
|
+
|
|
260
|
+
```swift
|
|
261
|
+
import AVFoundation
|
|
262
|
+
|
|
263
|
+
func cameraReady() async -> Bool {
|
|
264
|
+
let status = AVCaptureDevice.authorizationStatus(for: .video)
|
|
265
|
+
if status == .notDetermined {
|
|
266
|
+
return await AVCaptureDevice.requestAccess(for: .video)
|
|
267
|
+
}
|
|
268
|
+
return status == .authorized
|
|
269
|
+
}
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
When it returns `false`, show a `ContentUnavailableView` that explains how to
|
|
273
|
+
enable the camera.
|
|
274
|
+
|
|
275
|
+
## Review checklist
|
|
276
|
+
|
|
277
|
+
- [ ] `NSCameraUsageDescription` is present
|
|
278
|
+
- [ ] AR support is checked before any AR view appears
|
|
279
|
+
- [ ] Camera permission is requested and denial has fallback UI
|
|
280
|
+
- [ ] `arkit` is listed as required hardware only if the whole app is about AR
|
|
281
|
+
- [ ] The make closure loads models with `await`
|
|
282
|
+
- [ ] Make creates entities; update only changes them
|
|
283
|
+
- [ ] Interaction notes explain that `CollisionComponent` provides the hittable shape, paired with `InputTargetComponent`
|
|
284
|
+
- [ ] A Handoffs line mentions `AccessibilityComponent` and sends detailed SwiftUI and accessibility policy to the sibling skills
|
|
285
|
+
- [ ] Entity hit tests, `ray(...)` and ARKit surface raycasts are kept distinct
|
|
286
|
+
- [ ] Surface placement uses `ARSession.raycast(_:)` with `AnchorEntity(raycastResult:)`
|
|
287
|
+
- [ ] Per-frame logic uses `SceneEvents.Update`, not SwiftUI timers
|
|
288
|
+
- [ ] Large scenes load with async `ModelEntity(named:)`, not `Entity.load(named:)`
|
|
289
|
+
- [ ] Anchor targets match the kind of surface the feature needs
|
|
290
|
+
- [ ] Entities that update looks up have names
|
|
483
291
|
|
|
484
292
|
## References
|
|
485
293
|
|
|
486
|
-
-
|
|
487
|
-
- [RealityKit
|
|
488
|
-
- [RealityView](https://
|
|
489
|
-
- [RealityViewCameraContent](https://
|
|
490
|
-
- [RealityViewCamera](https://
|
|
491
|
-
- [Entity](https://
|
|
492
|
-
- [ModelEntity](https://
|
|
493
|
-
- [AnchorEntity](https://
|
|
494
|
-
- [ARKit
|
|
495
|
-
- [ARKit
|
|
496
|
-
- [
|
|
497
|
-
- [ARWorldTrackingConfiguration](https://
|
|
498
|
-
- [
|
|
499
|
-
- [
|
|
500
|
-
- [
|
|
294
|
+
- [Pattern catalogue](references/realitykit-patterns.md): physics, animation, materials and lighting, custom components and systems, occlusion, a SwiftUI model viewer, entity accessibility, performance
|
|
295
|
+
- [RealityKit](https://developer.apple.com/documentation/realitykit)
|
|
296
|
+
- [RealityView](https://developer.apple.com/documentation/realitykit/realityview)
|
|
297
|
+
- [RealityViewCameraContent](https://developer.apple.com/documentation/realitykit/realityviewcameracontent)
|
|
298
|
+
- [RealityViewCamera](https://developer.apple.com/documentation/realitykit/realityviewcamera)
|
|
299
|
+
- [Entity](https://developer.apple.com/documentation/realitykit/entity)
|
|
300
|
+
- [ModelEntity](https://developer.apple.com/documentation/realitykit/modelentity)
|
|
301
|
+
- [AnchorEntity](https://developer.apple.com/documentation/realitykit/anchorentity)
|
|
302
|
+
- [ARKit](https://developer.apple.com/documentation/arkit)
|
|
303
|
+
- [ARKit on iOS](https://developer.apple.com/documentation/arkit/arkit-in-ios)
|
|
304
|
+
- [Device support and permission checks](https://developer.apple.com/documentation/arkit/verifying-device-support-and-user-permission)
|
|
305
|
+
- [ARWorldTrackingConfiguration](https://developer.apple.com/documentation/arkit/arworldtrackingconfiguration)
|
|
306
|
+
- [Raycast query type](https://developer.apple.com/documentation/arkit/arraycastquery)
|
|
307
|
+
- [Session raycast method](https://developer.apple.com/documentation/arkit/arsession/raycast(_:))
|
|
308
|
+
- [Entity loading article](https://developer.apple.com/documentation/realitykit/loading-entities-from-a-file)
|