buildanything 1.7.1 → 2.0.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/.claude-plugin/marketplace.json +3 -3
- package/.claude-plugin/plugin.json +9 -3
- package/CHANGELOG.md +112 -0
- package/README.md +2 -2
- package/agents/a11y-architect.md +166 -0
- package/agents/business-model.md +80 -29
- package/agents/code-architect.md +75 -0
- package/agents/code-reviewer.md +255 -0
- package/agents/code-simplifier.md +64 -0
- package/agents/design-brand-guardian.md +293 -53
- package/agents/design-critic.md +139 -0
- package/agents/design-inclusive-visuals-specialist.md +6 -19
- package/agents/design-ui-designer.md +335 -56
- package/agents/design-ux-architect.md +403 -55
- package/agents/design-ux-researcher.md +264 -49
- package/agents/engineering-ai-engineer.md +26 -36
- package/agents/engineering-backend-architect.md +185 -36
- package/agents/engineering-data-engineer.md +225 -43
- package/agents/engineering-devops-automator.md +227 -74
- package/agents/engineering-frontend-developer.md +210 -34
- package/agents/engineering-mobile-app-builder.md +6 -1
- package/agents/engineering-rapid-prototyper.md +30 -9
- package/agents/engineering-security-engineer.md +263 -61
- package/agents/engineering-senior-developer.md +128 -19
- package/agents/engineering-sre.md +84 -0
- package/agents/engineering-technical-writer.md +285 -41
- package/agents/feature-intel.md +110 -0
- package/agents/ios-app-review-guardian.md +66 -0
- package/agents/ios-foundation-models-specialist.md +64 -0
- package/agents/ios-storekit-specialist.md +59 -0
- package/agents/ios-swift-architect.md +129 -0
- package/agents/ios-swift-search.md +137 -0
- package/agents/ios-swift-ui-design.md +136 -0
- package/agents/marketing-app-store-optimizer.md +246 -64
- package/agents/planner.md +216 -0
- package/agents/pr-test-analyzer.md +63 -0
- package/agents/product-feedback-synthesizer.md +8 -2
- package/agents/refactor-cleaner.md +102 -0
- package/agents/security-reviewer.md +128 -0
- package/agents/silent-failure-hunter.md +54 -0
- package/agents/swift-build-resolver.md +119 -0
- package/agents/swift-reviewer.md +112 -0
- package/agents/tech-feasibility.md +21 -1
- package/agents/testing-api-tester.md +236 -59
- package/agents/testing-evidence-collector.md +26 -1
- package/agents/testing-performance-benchmarker.md +21 -1
- package/agents/testing-reality-checker.md +6 -1
- package/agents/visual-research.md +116 -0
- package/bin/adapters/cycle-counter-tool.ts +155 -0
- package/bin/adapters/scribe-tool.ts +71 -0
- package/bin/adapters/state-save-tool.ts +130 -0
- package/bin/adapters/write-lease-tool.ts +127 -0
- package/bin/buildanything-runtime.js +15 -0
- package/bin/buildanything-runtime.ts +328 -0
- package/bin/setup.js +83 -8
- package/commands/add-feature.md +2 -0
- package/commands/build.md +752 -332
- package/commands/fix.md +65 -0
- package/commands/self-check.md +121 -0
- package/commands/setup.md +114 -0
- package/commands/ux-review.md +63 -0
- package/commands/verify.md +69 -0
- package/docs/migration/agents.yaml +729 -0
- package/docs/migration/phase-graph.yaml +1088 -0
- package/docs/migration/sdk-host-compat.md +18 -0
- package/hooks/compile-writer-owner-cache.ts +171 -0
- package/hooks/hooks.json +36 -0
- package/hooks/pre-tool-use +19 -0
- package/hooks/pre-tool-use.ts +776 -0
- package/hooks/record-mode-transitions.ts +178 -0
- package/hooks/session-start +89 -2
- package/hooks/subagent-start +17 -0
- package/hooks/subagent-start.ts +471 -0
- package/hooks/subagent-stop +17 -0
- package/hooks/subagent-stop.ts +153 -0
- package/package.json +28 -5
- package/protocols/architecture-schema.md +171 -0
- package/protocols/build-fix.md +52 -0
- package/protocols/cleanup.md +54 -0
- package/protocols/decision-log.md +131 -0
- package/protocols/eval-harness.md +61 -0
- package/protocols/fake-data-detector.md +64 -0
- package/protocols/ios-context.md +234 -0
- package/protocols/ios-frameworks-map.md +323 -0
- package/protocols/ios-phase-branches.md +337 -0
- package/protocols/ios-preflight.md +27 -0
- package/protocols/launch-readiness.md +258 -0
- package/protocols/metric-loop.md +153 -0
- package/protocols/smoke-test.md +118 -0
- package/protocols/state-schema.json +388 -0
- package/protocols/state-schema.md +172 -0
- package/protocols/verify.md +127 -0
- package/protocols/visual-dna.md +185 -0
- package/protocols/web-phase-branches.md +351 -0
- package/skills/ios/_VENDORED.md +62 -0
- package/skills/ios/activitykit/LICENSE +131 -0
- package/skills/ios/activitykit/SKILL.md +505 -0
- package/skills/ios/activitykit/references/activitykit-patterns.md +868 -0
- package/skills/ios/app-intents/LICENSE +131 -0
- package/skills/ios/app-intents/SKILL.md +494 -0
- package/skills/ios/app-intents/references/appintents-advanced.md +1076 -0
- package/skills/ios/app-store-connect-metadata/SKILL.md +148 -0
- package/skills/ios/apple-on-device-ai/LICENSE +131 -0
- package/skills/ios/apple-on-device-ai/SKILL.md +505 -0
- package/skills/ios/apple-on-device-ai/references/coreml-conversion.md +425 -0
- package/skills/ios/apple-on-device-ai/references/coreml-optimization.md +344 -0
- package/skills/ios/apple-on-device-ai/references/foundation-models.md +508 -0
- package/skills/ios/apple-on-device-ai/references/mlx-swift.md +285 -0
- package/skills/ios/asc-privacy-manifest/SKILL.md +350 -0
- package/skills/ios/hig-components-content/SKILL.md +86 -0
- package/skills/ios/hig-components-content/references/activity-views.md +79 -0
- package/skills/ios/hig-components-content/references/charts.md +180 -0
- package/skills/ios/hig-components-content/references/collections.md +48 -0
- package/skills/ios/hig-components-content/references/color-wells.md +42 -0
- package/skills/ios/hig-components-content/references/image-views.md +82 -0
- package/skills/ios/hig-components-content/references/image-wells.md +34 -0
- package/skills/ios/hig-components-content/references/lockups.md +78 -0
- package/skills/ios/hig-components-content/references/web-views.md +36 -0
- package/skills/ios/hig-components-controls/SKILL.md +88 -0
- package/skills/ios/hig-components-controls/references/combo-boxes.md +40 -0
- package/skills/ios/hig-components-controls/references/controls.md +112 -0
- package/skills/ios/hig-components-controls/references/gauges.md +74 -0
- package/skills/ios/hig-components-controls/references/labels.md +92 -0
- package/skills/ios/hig-components-controls/references/pickers.md +128 -0
- package/skills/ios/hig-components-controls/references/rating-indicators.md +38 -0
- package/skills/ios/hig-components-controls/references/segmented-controls.md +94 -0
- package/skills/ios/hig-components-controls/references/sliders.md +92 -0
- package/skills/ios/hig-components-controls/references/steppers.md +40 -0
- package/skills/ios/hig-components-controls/references/text-fields.md +88 -0
- package/skills/ios/hig-components-controls/references/text-views.md +56 -0
- package/skills/ios/hig-components-controls/references/toggles.md +127 -0
- package/skills/ios/hig-components-controls/references/token-fields.md +48 -0
- package/skills/ios/hig-components-controls/references/virtual-keyboards.md +156 -0
- package/skills/ios/hig-components-dialogs/SKILL.md +76 -0
- package/skills/ios/hig-components-dialogs/references/action-sheets.md +74 -0
- package/skills/ios/hig-components-dialogs/references/alerts.md +158 -0
- package/skills/ios/hig-components-dialogs/references/digit-entry-views.md +32 -0
- package/skills/ios/hig-components-dialogs/references/popovers.md +81 -0
- package/skills/ios/hig-components-dialogs/references/sheets.md +157 -0
- package/skills/ios/hig-components-layout/SKILL.md +99 -0
- package/skills/ios/hig-components-layout/references/boxes.md +48 -0
- package/skills/ios/hig-components-layout/references/column-views.md +44 -0
- package/skills/ios/hig-components-layout/references/lists-and-tables.md +99 -0
- package/skills/ios/hig-components-layout/references/ornaments.md +56 -0
- package/skills/ios/hig-components-layout/references/outline-views.md +64 -0
- package/skills/ios/hig-components-layout/references/panels.md +75 -0
- package/skills/ios/hig-components-layout/references/scroll-views.md +123 -0
- package/skills/ios/hig-components-layout/references/sidebars.md +109 -0
- package/skills/ios/hig-components-layout/references/split-views.md +110 -0
- package/skills/ios/hig-components-layout/references/tab-bars.md +173 -0
- package/skills/ios/hig-components-layout/references/tab-views.md +68 -0
- package/skills/ios/hig-components-layout/references/windows.md +188 -0
- package/skills/ios/hig-components-menus/SKILL.md +81 -0
- package/skills/ios/hig-components-menus/references/action-button.md +61 -0
- package/skills/ios/hig-components-menus/references/buttons.md +261 -0
- package/skills/ios/hig-components-menus/references/context-menus.md +105 -0
- package/skills/ios/hig-components-menus/references/disclosure-controls.md +84 -0
- package/skills/ios/hig-components-menus/references/dock-menus.md +40 -0
- package/skills/ios/hig-components-menus/references/edit-menus.md +88 -0
- package/skills/ios/hig-components-menus/references/menus.md +171 -0
- package/skills/ios/hig-components-menus/references/pop-up-buttons.md +70 -0
- package/skills/ios/hig-components-menus/references/pull-down-buttons.md +77 -0
- package/skills/ios/hig-components-menus/references/the-menu-bar.md +303 -0
- package/skills/ios/hig-components-menus/references/toolbars.md +256 -0
- package/skills/ios/hig-components-search/SKILL.md +68 -0
- package/skills/ios/hig-components-search/references/page-controls.md +120 -0
- package/skills/ios/hig-components-search/references/path-controls.md +40 -0
- package/skills/ios/hig-components-search/references/search-fields.md +189 -0
- package/skills/ios/hig-components-status/SKILL.md +80 -0
- package/skills/ios/hig-components-status/references/activity-rings.md +105 -0
- package/skills/ios/hig-components-status/references/progress-indicators.md +116 -0
- package/skills/ios/hig-components-status/references/status-bars.md +38 -0
- package/skills/ios/hig-components-system/SKILL.md +88 -0
- package/skills/ios/hig-components-system/references/app-clips.md +387 -0
- package/skills/ios/hig-components-system/references/app-shortcuts.md +114 -0
- package/skills/ios/hig-components-system/references/complications.md +425 -0
- package/skills/ios/hig-components-system/references/home-screen-quick-actions.md +42 -0
- package/skills/ios/hig-components-system/references/live-activities.md +442 -0
- package/skills/ios/hig-components-system/references/notifications.md +153 -0
- package/skills/ios/hig-components-system/references/top-shelf.md +135 -0
- package/skills/ios/hig-components-system/references/watch-faces.md +40 -0
- package/skills/ios/hig-components-system/references/widgets.md +517 -0
- package/skills/ios/hig-foundations/SKILL.md +98 -0
- package/skills/ios/hig-foundations/references/accessibility.md +291 -0
- package/skills/ios/hig-foundations/references/app-icons.md +210 -0
- package/skills/ios/hig-foundations/references/branding.md +44 -0
- package/skills/ios/hig-foundations/references/color.md +274 -0
- package/skills/ios/hig-foundations/references/dark-mode.md +116 -0
- package/skills/ios/hig-foundations/references/icons.md +263 -0
- package/skills/ios/hig-foundations/references/images.md +176 -0
- package/skills/ios/hig-foundations/references/immersive-experiences.md +174 -0
- package/skills/ios/hig-foundations/references/inclusion.md +189 -0
- package/skills/ios/hig-foundations/references/layout.md +425 -0
- package/skills/ios/hig-foundations/references/materials.md +238 -0
- package/skills/ios/hig-foundations/references/motion.md +103 -0
- package/skills/ios/hig-foundations/references/privacy.md +231 -0
- package/skills/ios/hig-foundations/references/right-to-left.md +206 -0
- package/skills/ios/hig-foundations/references/sf-symbols.md +310 -0
- package/skills/ios/hig-foundations/references/spatial-layout.md +142 -0
- package/skills/ios/hig-foundations/references/typography.md +1146 -0
- package/skills/ios/hig-foundations/references/writing.md +91 -0
- package/skills/ios/hig-inputs/SKILL.md +94 -0
- package/skills/ios/hig-inputs/references/apple-pencil-and-scribble.md +148 -0
- package/skills/ios/hig-inputs/references/camera-control.md +107 -0
- package/skills/ios/hig-inputs/references/digital-crown.md +83 -0
- package/skills/ios/hig-inputs/references/eyes.md +120 -0
- package/skills/ios/hig-inputs/references/focus-and-selection.md +120 -0
- package/skills/ios/hig-inputs/references/game-controls.md +156 -0
- package/skills/ios/hig-inputs/references/gestures.md +208 -0
- package/skills/ios/hig-inputs/references/gyro-and-accelerometer.md +40 -0
- package/skills/ios/hig-inputs/references/keyboards.md +234 -0
- package/skills/ios/hig-inputs/references/nearby-interactions.md +70 -0
- package/skills/ios/hig-inputs/references/pointing-devices.md +237 -0
- package/skills/ios/hig-inputs/references/remotes.md +67 -0
- package/skills/ios/hig-inputs/references/spatial-interactions.md +70 -0
- package/skills/ios/hig-patterns/SKILL.md +104 -0
- package/skills/ios/hig-patterns/references/charting-data.md +81 -0
- package/skills/ios/hig-patterns/references/collaboration-and-sharing.md +86 -0
- package/skills/ios/hig-patterns/references/drag-and-drop.md +134 -0
- package/skills/ios/hig-patterns/references/entering-data.md +69 -0
- package/skills/ios/hig-patterns/references/feedback.md +67 -0
- package/skills/ios/hig-patterns/references/file-management.md +135 -0
- package/skills/ios/hig-patterns/references/going-full-screen.md +79 -0
- package/skills/ios/hig-patterns/references/launching.md +81 -0
- package/skills/ios/hig-patterns/references/live-viewing-apps.md +79 -0
- package/skills/ios/hig-patterns/references/loading.md +59 -0
- package/skills/ios/hig-patterns/references/managing-accounts.md +107 -0
- package/skills/ios/hig-patterns/references/managing-notifications.md +99 -0
- package/skills/ios/hig-patterns/references/modality.md +82 -0
- package/skills/ios/hig-patterns/references/multitasking.md +131 -0
- package/skills/ios/hig-patterns/references/offering-help.md +117 -0
- package/skills/ios/hig-patterns/references/onboarding.md +69 -0
- package/skills/ios/hig-patterns/references/playing-audio.md +124 -0
- package/skills/ios/hig-patterns/references/playing-haptics.md +280 -0
- package/skills/ios/hig-patterns/references/playing-video.md +180 -0
- package/skills/ios/hig-patterns/references/printing.md +50 -0
- package/skills/ios/hig-patterns/references/ratings-and-reviews.md +48 -0
- package/skills/ios/hig-patterns/references/searching.md +70 -0
- package/skills/ios/hig-patterns/references/settings.md +84 -0
- package/skills/ios/hig-patterns/references/undo-and-redo.md +58 -0
- package/skills/ios/hig-patterns/references/workouts.md +76 -0
- package/skills/ios/hig-platforms/SKILL.md +84 -0
- package/skills/ios/hig-platforms/references/designing-for-games.md +159 -0
- package/skills/ios/hig-platforms/references/designing-for-ios.md +66 -0
- package/skills/ios/hig-platforms/references/designing-for-ipados.md +64 -0
- package/skills/ios/hig-platforms/references/designing-for-macos.md +70 -0
- package/skills/ios/hig-platforms/references/designing-for-tvos.md +68 -0
- package/skills/ios/hig-platforms/references/designing-for-visionos.md +85 -0
- package/skills/ios/hig-platforms/references/designing-for-watchos.md +74 -0
- package/skills/ios/hig-project-context/SKILL.md +133 -0
- package/skills/ios/hig-technologies/SKILL.md +107 -0
- package/skills/ios/hig-technologies/references/airplay.md +125 -0
- package/skills/ios/hig-technologies/references/always-on.md +62 -0
- package/skills/ios/hig-technologies/references/apple-pay.md +441 -0
- package/skills/ios/hig-technologies/references/augmented-reality.md +247 -0
- package/skills/ios/hig-technologies/references/carekit.md +224 -0
- package/skills/ios/hig-technologies/references/carplay.md +119 -0
- package/skills/ios/hig-technologies/references/game-center.md +343 -0
- package/skills/ios/hig-technologies/references/generative-ai.md +110 -0
- package/skills/ios/hig-technologies/references/healthkit.md +120 -0
- package/skills/ios/hig-technologies/references/homekit.md +343 -0
- package/skills/ios/hig-technologies/references/icloud.md +52 -0
- package/skills/ios/hig-technologies/references/id-verifier.md +73 -0
- package/skills/ios/hig-technologies/references/imessage-apps-and-stickers.md +105 -0
- package/skills/ios/hig-technologies/references/in-app-purchase.md +263 -0
- package/skills/ios/hig-technologies/references/live-photos.md +54 -0
- package/skills/ios/hig-technologies/references/mac-catalyst.md +216 -0
- package/skills/ios/hig-technologies/references/machine-learning.md +394 -0
- package/skills/ios/hig-technologies/references/maps.md +221 -0
- package/skills/ios/hig-technologies/references/nfc.md +51 -0
- package/skills/ios/hig-technologies/references/photo-editing.md +40 -0
- package/skills/ios/hig-technologies/references/researchkit.md +134 -0
- package/skills/ios/hig-technologies/references/shareplay.md +142 -0
- package/skills/ios/hig-technologies/references/shazamkit.md +47 -0
- package/skills/ios/hig-technologies/references/sign-in-with-apple.md +288 -0
- package/skills/ios/hig-technologies/references/siri.md +523 -0
- package/skills/ios/hig-technologies/references/tap-to-pay-on-iphone.md +208 -0
- package/skills/ios/hig-technologies/references/voiceover.md +90 -0
- package/skills/ios/hig-technologies/references/wallet.md +420 -0
- package/skills/ios/ios-26-platform/SKILL.md +53 -0
- package/skills/ios/ios-26-platform/references/automatic-adoption.md +161 -0
- package/skills/ios/ios-26-platform/references/backward-compat.md +238 -0
- package/skills/ios/ios-26-platform/references/liquid-glass.md +255 -0
- package/skills/ios/ios-26-platform/references/swiftui-apis.md +277 -0
- package/skills/ios/ios-26-platform/references/toolbar-navigation.md +250 -0
- package/skills/ios/ios-bootstrap/SKILL.md +107 -0
- package/skills/ios/ios-bootstrap/references/apple-docs-mcp-config.md +28 -0
- package/skills/ios/ios-bootstrap/references/new-project-dialog.md +41 -0
- package/skills/ios/ios-bootstrap/references/xcode-mcp-config.md +29 -0
- package/skills/ios/ios-debugger-agent/LICENSE +21 -0
- package/skills/ios/ios-debugger-agent/SKILL.md +58 -0
- package/skills/ios/ios-debugger-agent/agents/openai.yaml +4 -0
- package/skills/ios/ios-entitlements-generator/SKILL.md +47 -0
- package/skills/ios/ios-info-plist-hardening/SKILL.md +130 -0
- package/skills/ios/ios-maestro-flow-author/SKILL.md +68 -0
- package/skills/ios/ios-maestro-flow-author/references/input-and-scroll.yaml +17 -0
- package/skills/ios/ios-maestro-flow-author/references/modal-and-dismiss.yaml +14 -0
- package/skills/ios/ios-maestro-flow-author/references/onboarding-flow.yaml +16 -0
- package/skills/ios/ios-maestro-flow-author/references/tab-navigation.yaml +13 -0
- package/skills/ios/ios-maestro-flow-author/references/tap-and-assert.yaml +9 -0
- package/skills/ios/swift-accessibility/LICENSE +21 -0
- package/skills/ios/swift-accessibility/SKILL.md +371 -0
- package/skills/ios/swift-accessibility/examples/before-after-appkit.md +446 -0
- package/skills/ios/swift-accessibility/examples/before-after-swiftui.md +441 -0
- package/skills/ios/swift-accessibility/examples/before-after-uikit.md +464 -0
- package/skills/ios/swift-accessibility/references/assistive-access.md +441 -0
- package/skills/ios/swift-accessibility/references/display-settings.md +491 -0
- package/skills/ios/swift-accessibility/references/dynamic-type.md +420 -0
- package/skills/ios/swift-accessibility/references/media-accessibility.md +421 -0
- package/skills/ios/swift-accessibility/references/motor-input.md +393 -0
- package/skills/ios/swift-accessibility/references/nutrition-labels.md +362 -0
- package/skills/ios/swift-accessibility/references/platform-specifics.md +515 -0
- package/skills/ios/swift-accessibility/references/semantic-structure.md +585 -0
- package/skills/ios/swift-accessibility/references/testing-auditing.md +507 -0
- package/skills/ios/swift-accessibility/references/voice-control.md +317 -0
- package/skills/ios/swift-accessibility/references/voiceover-swiftui.md +584 -0
- package/skills/ios/swift-accessibility/references/voiceover-uikit.md +519 -0
- package/skills/ios/swift-accessibility/references/wcag-mapping.md +167 -0
- package/skills/ios/swift-accessibility/resources/audit-template.swift +128 -0
- package/skills/ios/swift-accessibility/resources/qa-checklist.md +258 -0
- package/skills/ios/swift-actor-persistence/SKILL.md +143 -0
- package/skills/ios/swift-concurrency/LICENSE +21 -0
- package/skills/ios/swift-concurrency/SKILL.md +171 -0
- package/skills/ios/swift-concurrency/references/_index.md +50 -0
- package/skills/ios/swift-concurrency/references/actors.md +660 -0
- package/skills/ios/swift-concurrency/references/async-algorithms.md +847 -0
- package/skills/ios/swift-concurrency/references/async-await-basics.md +266 -0
- package/skills/ios/swift-concurrency/references/async-sequences.md +710 -0
- package/skills/ios/swift-concurrency/references/core-data.md +560 -0
- package/skills/ios/swift-concurrency/references/glossary.md +135 -0
- package/skills/ios/swift-concurrency/references/linting.md +155 -0
- package/skills/ios/swift-concurrency/references/memory-management.md +569 -0
- package/skills/ios/swift-concurrency/references/migration.md +1104 -0
- package/skills/ios/swift-concurrency/references/performance.md +593 -0
- package/skills/ios/swift-concurrency/references/sendable.md +598 -0
- package/skills/ios/swift-concurrency/references/tasks.md +636 -0
- package/skills/ios/swift-concurrency/references/testing.md +592 -0
- package/skills/ios/swift-concurrency/references/threading.md +495 -0
- package/skills/ios/swift-concurrency-6-2/SKILL.md +216 -0
- package/skills/ios/swift-protocol-di-testing/SKILL.md +190 -0
- package/skills/ios/swift-security-expert/LICENSE +21 -0
- package/skills/ios/swift-security-expert/SKILL.md +470 -0
- package/skills/ios/swift-security-expert/references/biometric-authentication.md +565 -0
- package/skills/ios/swift-security-expert/references/certificate-trust.md +592 -0
- package/skills/ios/swift-security-expert/references/common-anti-patterns.md +690 -0
- package/skills/ios/swift-security-expert/references/compliance-owasp-mapping.md +537 -0
- package/skills/ios/swift-security-expert/references/credential-storage-patterns.md +721 -0
- package/skills/ios/swift-security-expert/references/cryptokit-public-key.md +505 -0
- package/skills/ios/swift-security-expert/references/cryptokit-symmetric.md +497 -0
- package/skills/ios/swift-security-expert/references/keychain-access-control.md +508 -0
- package/skills/ios/swift-security-expert/references/keychain-fundamentals.md +596 -0
- package/skills/ios/swift-security-expert/references/keychain-item-classes.md +476 -0
- package/skills/ios/swift-security-expert/references/keychain-sharing.md +458 -0
- package/skills/ios/swift-security-expert/references/migration-legacy-stores.md +727 -0
- package/skills/ios/swift-security-expert/references/secure-enclave.md +539 -0
- package/skills/ios/swift-security-expert/references/testing-security-code.md +781 -0
- package/skills/ios/swift-testing-expert/LICENSE +21 -0
- package/skills/ios/swift-testing-expert/SKILL.md +79 -0
- package/skills/ios/swift-testing-expert/references/_index.md +12 -0
- package/skills/ios/swift-testing-expert/references/async-testing-and-waiting.md +127 -0
- package/skills/ios/swift-testing-expert/references/expectations.md +145 -0
- package/skills/ios/swift-testing-expert/references/fundamentals.md +141 -0
- package/skills/ios/swift-testing-expert/references/migration-from-xctest.md +127 -0
- package/skills/ios/swift-testing-expert/references/parallelization-and-isolation.md +95 -0
- package/skills/ios/swift-testing-expert/references/parameterized-testing.md +284 -0
- package/skills/ios/swift-testing-expert/references/performance-and-best-practices.md +187 -0
- package/skills/ios/swift-testing-expert/references/traits-and-tags.md +114 -0
- package/skills/ios/swift-testing-expert/references/xcode-workflows.md +70 -0
- package/skills/ios/swiftdata-pro/LICENSE +21 -0
- package/skills/ios/swiftdata-pro/SKILL.md +102 -0
- package/skills/ios/swiftdata-pro/agents/openai.yaml +10 -0
- package/skills/ios/swiftdata-pro/assets/swiftdata-pro-icon.png +0 -0
- package/skills/ios/swiftdata-pro/assets/swiftdata-pro-icon.svg +29 -0
- package/skills/ios/swiftdata-pro/references/class-inheritance.md +104 -0
- package/skills/ios/swiftdata-pro/references/cloudkit.md +10 -0
- package/skills/ios/swiftdata-pro/references/core-rules.md +20 -0
- package/skills/ios/swiftdata-pro/references/indexing.md +27 -0
- package/skills/ios/swiftdata-pro/references/predicates.md +73 -0
- package/skills/ios/swiftui-design-principles/AGENTS.md +21 -0
- package/skills/ios/swiftui-design-principles/LICENSE +21 -0
- package/skills/ios/swiftui-design-principles/README.md +41 -0
- package/skills/ios/swiftui-design-principles/SKILL.md +605 -0
- package/skills/ios/swiftui-design-principles/metadata.json +10 -0
- package/skills/ios/swiftui-design-tokens/SKILL.md +475 -0
- package/skills/ios/swiftui-liquid-glass/LICENSE +21 -0
- package/skills/ios/swiftui-liquid-glass/SKILL.md +95 -0
- package/skills/ios/swiftui-liquid-glass/agents/openai.yaml +4 -0
- package/skills/ios/swiftui-liquid-glass/references/liquid-glass.md +280 -0
- package/skills/ios/swiftui-performance-audit/LICENSE +21 -0
- package/skills/ios/swiftui-performance-audit/SKILL.md +111 -0
- package/skills/ios/swiftui-performance-audit/agents/openai.yaml +4 -0
- package/skills/ios/swiftui-performance-audit/references/code-smells.md +150 -0
- package/skills/ios/swiftui-performance-audit/references/demystify-swiftui-performance-wwdc23.md +46 -0
- package/skills/ios/swiftui-performance-audit/references/optimizing-swiftui-performance-instruments.md +29 -0
- package/skills/ios/swiftui-performance-audit/references/profiling-intake.md +44 -0
- package/skills/ios/swiftui-performance-audit/references/report-template.md +47 -0
- package/skills/ios/swiftui-performance-audit/references/understanding-hangs-in-your-app.md +33 -0
- package/skills/ios/swiftui-performance-audit/references/understanding-improving-swiftui-performance.md +52 -0
- package/skills/ios/swiftui-pro/LICENSE +21 -0
- package/skills/ios/swiftui-pro/SKILL.md +108 -0
- package/skills/ios/swiftui-pro/agents/openai.yaml +10 -0
- package/skills/ios/swiftui-pro/assets/swiftui-pro-icon.png +0 -0
- package/skills/ios/swiftui-pro/assets/swiftui-pro-icon.svg +29 -0
- package/skills/ios/swiftui-pro/references/accessibility.md +13 -0
- package/skills/ios/swiftui-pro/references/api.md +39 -0
- package/skills/ios/swiftui-pro/references/data.md +43 -0
- package/skills/ios/swiftui-pro/references/design.md +31 -0
- package/skills/ios/swiftui-pro/references/hygiene.md +9 -0
- package/skills/ios/swiftui-pro/references/navigation.md +14 -0
- package/skills/ios/swiftui-pro/references/performance.md +46 -0
- package/skills/ios/swiftui-pro/references/swift.md +56 -0
- package/skills/ios/swiftui-pro/references/views.md +35 -0
- package/skills/ios/swiftui-ui-patterns/LICENSE +21 -0
- package/skills/ios/swiftui-ui-patterns/SKILL.md +100 -0
- package/skills/ios/swiftui-ui-patterns/agents/openai.yaml +4 -0
- package/skills/ios/swiftui-ui-patterns/references/app-wiring.md +201 -0
- package/skills/ios/swiftui-ui-patterns/references/async-state.md +96 -0
- package/skills/ios/swiftui-ui-patterns/references/components-index.md +50 -0
- package/skills/ios/swiftui-ui-patterns/references/controls.md +57 -0
- package/skills/ios/swiftui-ui-patterns/references/deeplinks.md +66 -0
- package/skills/ios/swiftui-ui-patterns/references/focus.md +90 -0
- package/skills/ios/swiftui-ui-patterns/references/form.md +97 -0
- package/skills/ios/swiftui-ui-patterns/references/grids.md +71 -0
- package/skills/ios/swiftui-ui-patterns/references/haptics.md +71 -0
- package/skills/ios/swiftui-ui-patterns/references/input-toolbar.md +51 -0
- package/skills/ios/swiftui-ui-patterns/references/lightweight-clients.md +93 -0
- package/skills/ios/swiftui-ui-patterns/references/list.md +86 -0
- package/skills/ios/swiftui-ui-patterns/references/loading-placeholders.md +38 -0
- package/skills/ios/swiftui-ui-patterns/references/macos-settings.md +71 -0
- package/skills/ios/swiftui-ui-patterns/references/matched-transitions.md +59 -0
- package/skills/ios/swiftui-ui-patterns/references/media.md +73 -0
- package/skills/ios/swiftui-ui-patterns/references/menu-bar.md +101 -0
- package/skills/ios/swiftui-ui-patterns/references/navigationstack.md +159 -0
- package/skills/ios/swiftui-ui-patterns/references/overlay.md +45 -0
- package/skills/ios/swiftui-ui-patterns/references/performance.md +62 -0
- package/skills/ios/swiftui-ui-patterns/references/previews.md +48 -0
- package/skills/ios/swiftui-ui-patterns/references/scroll-reveal.md +133 -0
- package/skills/ios/swiftui-ui-patterns/references/scrollview.md +87 -0
- package/skills/ios/swiftui-ui-patterns/references/searchable.md +71 -0
- package/skills/ios/swiftui-ui-patterns/references/sheets.md +155 -0
- package/skills/ios/swiftui-ui-patterns/references/split-views.md +72 -0
- package/skills/ios/swiftui-ui-patterns/references/tabview.md +114 -0
- package/skills/ios/swiftui-ui-patterns/references/theming.md +71 -0
- package/skills/ios/swiftui-ui-patterns/references/title-menus.md +93 -0
- package/skills/ios/swiftui-ui-patterns/references/top-bar.md +49 -0
- package/skills/ios/swiftui-view-refactor/LICENSE +21 -0
- package/skills/ios/swiftui-view-refactor/SKILL.md +207 -0
- package/skills/ios/swiftui-view-refactor/agents/openai.yaml +4 -0
- package/skills/ios/swiftui-view-refactor/references/mv-patterns.md +161 -0
- package/skills/ios/widgetkit/LICENSE +131 -0
- package/skills/ios/widgetkit/SKILL.md +502 -0
- package/skills/ios/widgetkit/references/widgetkit-advanced.md +871 -0
- package/skills/ios/writing-for-interfaces/SKILL.md +75 -0
- package/skills/web/accessibility/SKILL.md +146 -0
- package/skills/web/aceternity-ui/SKILL.md +719 -0
- package/skills/web/aceternity-ui/metadata.json +10 -0
- package/skills/web/api-design/SKILL.md +523 -0
- package/skills/web/chart-accessibility/SKILL.md +332 -0
- package/skills/web/composition-patterns/AGENTS.md +946 -0
- package/skills/web/composition-patterns/README.md +60 -0
- package/skills/web/composition-patterns/SKILL.md +89 -0
- package/skills/web/composition-patterns/metadata.json +11 -0
- package/skills/web/composition-patterns/rules/_sections.md +29 -0
- package/skills/web/composition-patterns/rules/_template.md +24 -0
- package/skills/web/composition-patterns/rules/architecture-avoid-boolean-props.md +100 -0
- package/skills/web/composition-patterns/rules/architecture-compound-components.md +112 -0
- package/skills/web/composition-patterns/rules/patterns-children-over-render-props.md +87 -0
- package/skills/web/composition-patterns/rules/patterns-explicit-variants.md +100 -0
- package/skills/web/composition-patterns/rules/react19-no-forwardref.md +42 -0
- package/skills/web/composition-patterns/rules/state-context-interface.md +191 -0
- package/skills/web/composition-patterns/rules/state-decouple-implementation.md +113 -0
- package/skills/web/composition-patterns/rules/state-lift-state.md +125 -0
- package/skills/web/cost-aware-llm-pipeline/SKILL.md +183 -0
- package/skills/web/database-migrations/SKILL.md +429 -0
- package/skills/web/deployment-patterns/SKILL.md +427 -0
- package/skills/web/docker-patterns/SKILL.md +364 -0
- package/skills/web/e2e-testing/SKILL.md +326 -0
- package/skills/web/lighthouse-ci/SKILL.md +361 -0
- package/skills/web/mcp-server-patterns/SKILL.md +69 -0
- package/skills/web/next-best-practices/SKILL.md +153 -0
- package/skills/web/next-best-practices/async-patterns.md +87 -0
- package/skills/web/next-best-practices/bundling.md +180 -0
- package/skills/web/next-best-practices/data-patterns.md +297 -0
- package/skills/web/next-best-practices/debug-tricks.md +105 -0
- package/skills/web/next-best-practices/directives.md +73 -0
- package/skills/web/next-best-practices/error-handling.md +227 -0
- package/skills/web/next-best-practices/file-conventions.md +140 -0
- package/skills/web/next-best-practices/font.md +245 -0
- package/skills/web/next-best-practices/functions.md +108 -0
- package/skills/web/next-best-practices/hydration-error.md +91 -0
- package/skills/web/next-best-practices/image.md +173 -0
- package/skills/web/next-best-practices/metadata.md +301 -0
- package/skills/web/next-best-practices/parallel-routes.md +287 -0
- package/skills/web/next-best-practices/route-handlers.md +146 -0
- package/skills/web/next-best-practices/rsc-boundaries.md +159 -0
- package/skills/web/next-best-practices/runtime-selection.md +39 -0
- package/skills/web/next-best-practices/scripts.md +141 -0
- package/skills/web/next-best-practices/self-hosting.md +371 -0
- package/skills/web/next-best-practices/suspense-boundaries.md +67 -0
- package/skills/web/next-cache-components/SKILL.md +411 -0
- package/skills/web/postgres-best-practices/SKILL.md +14 -0
- package/skills/web/postgres-best-practices/references/schema-design.md +9 -0
- package/skills/web/react-best-practices/AGENTS.md +3810 -0
- package/skills/web/react-best-practices/README.md +123 -0
- package/skills/web/react-best-practices/SKILL.md +149 -0
- package/skills/web/react-best-practices/metadata.json +15 -0
- package/skills/web/react-best-practices/rules/_sections.md +46 -0
- package/skills/web/react-best-practices/rules/_template.md +28 -0
- package/skills/web/react-best-practices/rules/advanced-effect-event-deps.md +56 -0
- package/skills/web/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/skills/web/react-best-practices/rules/advanced-init-once.md +42 -0
- package/skills/web/react-best-practices/rules/advanced-use-latest.md +39 -0
- package/skills/web/react-best-practices/rules/async-api-routes.md +38 -0
- package/skills/web/react-best-practices/rules/async-cheap-condition-before-await.md +37 -0
- package/skills/web/react-best-practices/rules/async-defer-await.md +82 -0
- package/skills/web/react-best-practices/rules/async-dependencies.md +51 -0
- package/skills/web/react-best-practices/rules/async-parallel.md +28 -0
- package/skills/web/react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/skills/web/react-best-practices/rules/bundle-analyzable-paths.md +63 -0
- package/skills/web/react-best-practices/rules/bundle-barrel-imports.md +60 -0
- package/skills/web/react-best-practices/rules/bundle-conditional.md +31 -0
- package/skills/web/react-best-practices/rules/bundle-defer-third-party.md +49 -0
- package/skills/web/react-best-practices/rules/bundle-dynamic-imports.md +35 -0
- package/skills/web/react-best-practices/rules/bundle-preload.md +50 -0
- package/skills/web/react-best-practices/rules/client-event-listeners.md +74 -0
- package/skills/web/react-best-practices/rules/client-localstorage-schema.md +71 -0
- package/skills/web/react-best-practices/rules/client-passive-event-listeners.md +48 -0
- package/skills/web/react-best-practices/rules/client-swr-dedup.md +56 -0
- package/skills/web/react-best-practices/rules/js-batch-dom-css.md +107 -0
- package/skills/web/react-best-practices/rules/js-cache-function-results.md +80 -0
- package/skills/web/react-best-practices/rules/js-cache-property-access.md +28 -0
- package/skills/web/react-best-practices/rules/js-cache-storage.md +70 -0
- package/skills/web/react-best-practices/rules/js-combine-iterations.md +32 -0
- package/skills/web/react-best-practices/rules/js-early-exit.md +50 -0
- package/skills/web/react-best-practices/rules/js-flatmap-filter.md +60 -0
- package/skills/web/react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/skills/web/react-best-practices/rules/js-index-maps.md +37 -0
- package/skills/web/react-best-practices/rules/js-length-check-first.md +49 -0
- package/skills/web/react-best-practices/rules/js-min-max-loop.md +82 -0
- package/skills/web/react-best-practices/rules/js-request-idle-callback.md +105 -0
- package/skills/web/react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/skills/web/react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/skills/web/react-best-practices/rules/rendering-activity.md +26 -0
- package/skills/web/react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
- package/skills/web/react-best-practices/rules/rendering-conditional-render.md +40 -0
- package/skills/web/react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/skills/web/react-best-practices/rules/rendering-hoist-jsx.md +46 -0
- package/skills/web/react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
- package/skills/web/react-best-practices/rules/rendering-hydration-suppress-warning.md +30 -0
- package/skills/web/react-best-practices/rules/rendering-resource-hints.md +85 -0
- package/skills/web/react-best-practices/rules/rendering-script-defer-async.md +68 -0
- package/skills/web/react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/skills/web/react-best-practices/rules/rendering-usetransition-loading.md +75 -0
- package/skills/web/react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/skills/web/react-best-practices/rules/rerender-dependencies.md +45 -0
- package/skills/web/react-best-practices/rules/rerender-derived-state-no-effect.md +40 -0
- package/skills/web/react-best-practices/rules/rerender-derived-state.md +29 -0
- package/skills/web/react-best-practices/rules/rerender-functional-setstate.md +74 -0
- package/skills/web/react-best-practices/rules/rerender-lazy-state-init.md +58 -0
- package/skills/web/react-best-practices/rules/rerender-memo-with-default-value.md +38 -0
- package/skills/web/react-best-practices/rules/rerender-memo.md +44 -0
- package/skills/web/react-best-practices/rules/rerender-move-effect-to-event.md +45 -0
- package/skills/web/react-best-practices/rules/rerender-no-inline-components.md +82 -0
- package/skills/web/react-best-practices/rules/rerender-simple-expression-in-memo.md +35 -0
- package/skills/web/react-best-practices/rules/rerender-split-combined-hooks.md +64 -0
- package/skills/web/react-best-practices/rules/rerender-transitions.md +40 -0
- package/skills/web/react-best-practices/rules/rerender-use-deferred-value.md +59 -0
- package/skills/web/react-best-practices/rules/rerender-use-ref-transient-values.md +73 -0
- package/skills/web/react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/skills/web/react-best-practices/rules/server-auth-actions.md +96 -0
- package/skills/web/react-best-practices/rules/server-cache-lru.md +41 -0
- package/skills/web/react-best-practices/rules/server-cache-react.md +76 -0
- package/skills/web/react-best-practices/rules/server-dedup-props.md +65 -0
- package/skills/web/react-best-practices/rules/server-hoist-static-io.md +149 -0
- package/skills/web/react-best-practices/rules/server-no-shared-module-state.md +50 -0
- package/skills/web/react-best-practices/rules/server-parallel-fetching.md +83 -0
- package/skills/web/react-best-practices/rules/server-parallel-nested-fetching.md +34 -0
- package/skills/web/react-best-practices/rules/server-serialization.md +38 -0
- package/skills/web/seo/SKILL.md +154 -0
- package/skills/web/web-design-guidelines/SKILL.md +39 -0
- package/skills/web/zap-scan-config/SKILL.md +444 -0
- package/skills/web/zap-scan-config/assets/.gitkeep +9 -0
- package/skills/web/zap-scan-config/assets/github_action.yml +207 -0
- package/skills/web/zap-scan-config/assets/gitlab_ci.yml +226 -0
- package/skills/web/zap-scan-config/assets/zap_automation.yaml +196 -0
- package/skills/web/zap-scan-config/assets/zap_context.xml +192 -0
- package/skills/web/zap-scan-config/references/EXAMPLE.md +40 -0
- package/skills/web/zap-scan-config/references/api_testing_guide.md +475 -0
- package/skills/web/zap-scan-config/references/authentication_guide.md +431 -0
- package/skills/web/zap-scan-config/references/false_positive_handling.md +427 -0
- package/skills/web/zap-scan-config/references/owasp_mapping.md +255 -0
- package/src/lrr/aggregator.ts +80 -0
- package/src/orchestrator/hooks/context-header.ts +95 -0
- package/src/orchestrator/hooks/token-accounting-emitter.ts +77 -0
- package/src/orchestrator/hooks/token-accounting.ts +101 -0
- package/src/orchestrator/mcp/cycle-counter.ts +129 -0
- package/src/orchestrator/mcp/scribe.ts +283 -0
- package/src/orchestrator/mcp/state-save.ts +149 -0
- package/src/orchestrator/mcp/write-lease.ts +167 -0
- package/src/orchestrator/phase4-shared-context.ts +41 -0
- package/src/orchestrator/schemas/backward-edge.ts +46 -0
- package/agents/agentic-identity-trust.md +0 -121
- package/agents/data-consolidation-agent.md +0 -39
- package/agents/design-image-prompt-engineer.md +0 -105
- package/agents/design-visual-storyteller.md +0 -147
- package/agents/design-whimsy-injector.md +0 -89
- package/agents/engineering-autonomous-optimization-architect.md +0 -105
- package/agents/market-intel.md +0 -35
- package/agents/marketing-instagram-curator.md +0 -111
- package/agents/marketing-reddit-community-builder.md +0 -121
- package/agents/marketing-social-media-strategist.md +0 -74
- package/agents/marketing-tiktok-strategist.md +0 -123
- package/agents/marketing-twitter-engager.md +0 -124
- package/agents/marketing-wechat-official-account.md +0 -143
- package/agents/marketing-xiaohongshu-specialist.md +0 -136
- package/agents/marketing-zhihu-strategist.md +0 -160
- package/agents/product-behavioral-nudge-engine.md +0 -78
- package/agents/project-management-experiment-tracker.md +0 -102
- package/agents/report-distribution-agent.md +0 -43
- package/agents/risk-analysis.md +0 -45
- package/agents/sales-data-extraction-agent.md +0 -46
- package/agents/specialized-cultural-intelligence-strategist.md +0 -65
- package/agents/specialized-developer-advocate.md +0 -146
- package/agents/support-analytics-reporter.md +0 -133
- package/agents/support-executive-summary-generator.md +0 -64
- package/agents/support-finance-tracker.md +0 -145
- package/agents/support-legal-compliance-checker.md +0 -129
- package/agents/support-support-responder.md +0 -91
- package/agents/testing-accessibility-auditor.md +0 -110
- package/agents/testing-test-results-analyzer.md +0 -97
- package/agents/testing-tool-evaluator.md +0 -76
- package/agents/testing-workflow-optimizer.md +0 -99
- package/agents/user-research.md +0 -40
|
@@ -0,0 +1,519 @@
|
|
|
1
|
+
# VoiceOver — UIKit
|
|
2
|
+
|
|
3
|
+
## Contents
|
|
4
|
+
- [Core UIAccessibility Properties](#core-uiaccessibility-properties)
|
|
5
|
+
- [UIAccessibilityTraits Reference](#uiaccessibilitytraits-reference)
|
|
6
|
+
- [UIAccessibilityElement - Custom Elements](#uiaccessibilityelement---custom-elements)
|
|
7
|
+
- [UIAccessibilityContainer - Element Ordering](#uiaccessibilitycontainer---element-ordering)
|
|
8
|
+
- [UIAccessibilityCustomAction - Custom Actions](#uiaccessibilitycustomaction---custom-actions)
|
|
9
|
+
- [UIAccessibilityCustomRotor - Custom Navigation](#uiaccessibilitycustomrotor---custom-navigation)
|
|
10
|
+
- [Notifications - Announcements and Focus](#notifications---announcements-and-focus)
|
|
11
|
+
- [UIAccessibilityReadingContent](#uiaccessibilityreadingcontent)
|
|
12
|
+
- [Modal Views](#modal-views)
|
|
13
|
+
- [Custom Control Patterns](#custom-control-patterns)
|
|
14
|
+
- [NSAttributedString Accessibility Attributes](#nsattributedstring-accessibility-attributes)
|
|
15
|
+
- [Common Mistakes](#common-mistakes)
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## Core UIAccessibility Properties
|
|
20
|
+
|
|
21
|
+
Every `UIView` subclass exposes these properties. Override them to provide accessibility information.
|
|
22
|
+
|
|
23
|
+
```swift
|
|
24
|
+
class RatingView: UIView {
|
|
25
|
+
var rating: Int = 0 {
|
|
26
|
+
didSet {
|
|
27
|
+
// Notify VoiceOver that value changed
|
|
28
|
+
UIAccessibility.post(notification: .layoutChanged, argument: self)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// REQUIRED: opt this view into the accessibility tree
|
|
33
|
+
override var isAccessibilityElement: Bool {
|
|
34
|
+
get { true }
|
|
35
|
+
set { }
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
override var accessibilityLabel: String? {
|
|
39
|
+
get { "Rating" }
|
|
40
|
+
set { }
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
override var accessibilityValue: String? {
|
|
44
|
+
get { "\(rating) out of 5 stars" }
|
|
45
|
+
set { }
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
override var accessibilityHint: String? {
|
|
49
|
+
get { "Double-tap and hold, then swipe up or down to change" }
|
|
50
|
+
set { }
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
override var accessibilityTraits: UIAccessibilityTraits {
|
|
54
|
+
get { .adjustable }
|
|
55
|
+
set { }
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Support increment/decrement gestures (VoiceOver swipe up/down)
|
|
59
|
+
override func accessibilityIncrement() {
|
|
60
|
+
rating = min(5, rating + 1)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
override func accessibilityDecrement() {
|
|
64
|
+
rating = max(0, rating - 1)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Key Properties
|
|
70
|
+
|
|
71
|
+
| Property | Type | Purpose |
|
|
72
|
+
|---|---|---|
|
|
73
|
+
| `isAccessibilityElement` | `Bool` | Opt view into accessibility tree |
|
|
74
|
+
| `accessibilityLabel` | `String?` | Announced name (required for non-text elements) |
|
|
75
|
+
| `accessibilityHint` | `String?` | Describes the result of activating |
|
|
76
|
+
| `accessibilityValue` | `String?` | Current value (sliders, progress) |
|
|
77
|
+
| `accessibilityTraits` | `UIAccessibilityTraits` | Semantic role and state |
|
|
78
|
+
| `accessibilityFrame` | `CGRect` | Accessibility hit area (in screen coordinates) |
|
|
79
|
+
| `accessibilityPath` | `UIBezierPath?` | Custom non-rectangular hit area |
|
|
80
|
+
| `accessibilityActivationPoint` | `CGPoint` | Precise tap point |
|
|
81
|
+
| `accessibilityViewIsModal` | `Bool` | Constrain VoiceOver focus to this view |
|
|
82
|
+
| `shouldGroupAccessibilityChildren` | `Bool` | Group children for scanning |
|
|
83
|
+
| `accessibilityNavigationStyle` | `UIAccessibilityNavigationStyle` | `.automatic` / `.combined` / `.separate` |
|
|
84
|
+
| `accessibilityCustomActions` | `[UIAccessibilityCustomAction]?` | Custom action list |
|
|
85
|
+
| `accessibilityCustomRotors` | `[UIAccessibilityCustomRotor]?` | Custom rotor navigation |
|
|
86
|
+
| `accessibilityContainerType` | `UIAccessibilityContainerType` | `.none` / `.list` / `.landmark` / `.semanticGroup` / `.table` / `.dataTable` |
|
|
87
|
+
|
|
88
|
+
### `accessibilityFrame` — Custom Hit Area
|
|
89
|
+
|
|
90
|
+
By default, `accessibilityFrame` matches the view's frame in screen coordinates. Override when the visual and accessible areas differ.
|
|
91
|
+
|
|
92
|
+
```swift
|
|
93
|
+
override var accessibilityFrame: CGRect {
|
|
94
|
+
// Convert to screen coordinates
|
|
95
|
+
return UIAccessibility.convertToScreenCoordinates(bounds, in: self)
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Extend hit area to 44pt minimum
|
|
99
|
+
override var accessibilityFrame: CGRect {
|
|
100
|
+
let frame = convert(bounds, to: nil)
|
|
101
|
+
let minSize: CGFloat = 44
|
|
102
|
+
let expandX = max(0, (minSize - frame.width) / 2)
|
|
103
|
+
let expandY = max(0, (minSize - frame.height) / 2)
|
|
104
|
+
return frame.insetBy(dx: -expandX, dy: -expandY)
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
## UIAccessibilityTraits Reference
|
|
111
|
+
|
|
112
|
+
Traits can be combined with `|` (union).
|
|
113
|
+
|
|
114
|
+
```swift
|
|
115
|
+
accessibilityTraits = [.button, .selected]
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
| Trait | When to Use |
|
|
119
|
+
|---|---|
|
|
120
|
+
| `.button` | Any tappable element that isn't a `UIButton` |
|
|
121
|
+
| `.link` | Opens a URL or navigates outside the app |
|
|
122
|
+
| `.header` | Section or page header |
|
|
123
|
+
| `.selected` | Currently selected item |
|
|
124
|
+
| `.image` | Image view (decorative or informational) |
|
|
125
|
+
| `.searchField` | Search text field |
|
|
126
|
+
| `.playsSound` | Activation plays audio |
|
|
127
|
+
| `.keyboardKey` | Custom keyboard key |
|
|
128
|
+
| `.staticText` | Non-interactive display text |
|
|
129
|
+
| `.summaryElement` | Spoken when app first launches |
|
|
130
|
+
| `.notEnabled` | Disabled/unavailable control |
|
|
131
|
+
| `.updatesFrequently` | Live region — re-read on value change |
|
|
132
|
+
| `.startsMediaSession` | Starts audio/video playback |
|
|
133
|
+
| `.adjustable` | Supports increment/decrement |
|
|
134
|
+
| `.allowsDirectInteraction` | Passes raw touches (piano keys, drawing) |
|
|
135
|
+
| `.causesPageTurn` | Triggers a page turn in reading apps |
|
|
136
|
+
| `.tabBar` | Tab bar (system-handled) |
|
|
137
|
+
|
|
138
|
+
### State via Traits
|
|
139
|
+
|
|
140
|
+
```swift
|
|
141
|
+
// ✅ Selected state as trait
|
|
142
|
+
cell.accessibilityTraits = isSelected ? [.button, .selected] : .button
|
|
143
|
+
|
|
144
|
+
// ❌ State embedded in label (breaks automation and is verbose)
|
|
145
|
+
cell.accessibilityLabel = isSelected ? "Photos, selected" : "Photos"
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## UIAccessibilityElement - Custom Elements
|
|
151
|
+
|
|
152
|
+
Use when content is drawn in a custom view (`drawRect`, Core Graphics, Metal) with no native subviews. `UIAccessibilityElement` creates virtual elements over the custom-drawn content.
|
|
153
|
+
|
|
154
|
+
```swift
|
|
155
|
+
class GraphView: UIView {
|
|
156
|
+
var bars: [BarData] = []
|
|
157
|
+
|
|
158
|
+
// Cache elements — recreate when data changes
|
|
159
|
+
private var _accessibilityElements: [UIAccessibilityElement]?
|
|
160
|
+
|
|
161
|
+
override var isAccessibilityElement: Bool {
|
|
162
|
+
get { false } // Container itself is NOT an element
|
|
163
|
+
set { }
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
override var accessibilityElements: [Any]? {
|
|
167
|
+
get {
|
|
168
|
+
if _accessibilityElements == nil {
|
|
169
|
+
_accessibilityElements = bars.enumerated().map { index, bar in
|
|
170
|
+
let element = UIAccessibilityElement(accessibilityContainer: self)
|
|
171
|
+
element.accessibilityLabel = bar.label
|
|
172
|
+
element.accessibilityValue = "\(bar.value) units"
|
|
173
|
+
element.accessibilityTraits = .staticText
|
|
174
|
+
// Convert bar's CGRect to screen coordinates
|
|
175
|
+
let barFrame = frameForBar(at: index)
|
|
176
|
+
element.accessibilityFrame = UIAccessibility.convertToScreenCoordinates(barFrame, in: self)
|
|
177
|
+
return element
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
return _accessibilityElements
|
|
181
|
+
}
|
|
182
|
+
set { _accessibilityElements = newValue as? [UIAccessibilityElement] }
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
func dataDidChange() {
|
|
186
|
+
_accessibilityElements = nil
|
|
187
|
+
// Tell VoiceOver the layout changed
|
|
188
|
+
UIAccessibility.post(notification: .layoutChanged, argument: nil)
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
## UIAccessibilityContainer - Element Ordering
|
|
196
|
+
|
|
197
|
+
When a view contains multiple subviews that should be navigated in a specific order, implement `UIAccessibilityContainer` by providing `accessibilityElements`.
|
|
198
|
+
|
|
199
|
+
```swift
|
|
200
|
+
class DashboardView: UIView {
|
|
201
|
+
@IBOutlet var headerView: UIView!
|
|
202
|
+
@IBOutlet var chartView: UIView!
|
|
203
|
+
@IBOutlet var summaryLabel: UILabel!
|
|
204
|
+
@IBOutlet var actionButton: UIButton!
|
|
205
|
+
|
|
206
|
+
// Return elements in the desired reading order
|
|
207
|
+
override var accessibilityElements: [Any]? {
|
|
208
|
+
get { [headerView!, summaryLabel!, chartView!, actionButton!] }
|
|
209
|
+
set { }
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
```
|
|
213
|
+
|
|
214
|
+
### `accessibilityContainerType`
|
|
215
|
+
|
|
216
|
+
Provides semantic meaning to containers. VoiceOver announces container type changes.
|
|
217
|
+
|
|
218
|
+
```swift
|
|
219
|
+
tableContainerView.accessibilityContainerType = .dataTable
|
|
220
|
+
listView.accessibilityContainerType = .list
|
|
221
|
+
navContainerView.accessibilityContainerType = .landmark
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
### `shouldGroupAccessibilityChildren`
|
|
225
|
+
|
|
226
|
+
Groups all children into a single node for Switch Control scanning. Does NOT merge for VoiceOver navigation.
|
|
227
|
+
|
|
228
|
+
```swift
|
|
229
|
+
groupView.shouldGroupAccessibilityChildren = true
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## UIAccessibilityCustomAction - Custom Actions
|
|
235
|
+
|
|
236
|
+
Adds entries to VoiceOver's Actions rotor (double-tap and hold → swipe up/down). Essential for swipe-to-reveal and long-press menus.
|
|
237
|
+
|
|
238
|
+
```swift
|
|
239
|
+
class MessageCell: UITableViewCell {
|
|
240
|
+
override var accessibilityCustomActions: [UIAccessibilityCustomAction]? {
|
|
241
|
+
get {
|
|
242
|
+
[
|
|
243
|
+
UIAccessibilityCustomAction(name: "Reply", target: self, selector: #selector(reply)),
|
|
244
|
+
UIAccessibilityCustomAction(name: "Forward", target: self, selector: #selector(forward)),
|
|
245
|
+
UIAccessibilityCustomAction(name: "Delete", image: UIImage(systemName: "trash")) { [weak self] _ in
|
|
246
|
+
self?.deleteMessage()
|
|
247
|
+
return true
|
|
248
|
+
}
|
|
249
|
+
]
|
|
250
|
+
}
|
|
251
|
+
set { }
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
@objc private func reply() -> Bool {
|
|
255
|
+
replyToMessage()
|
|
256
|
+
return true // return true = action succeeded
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
@objc private func forward() -> Bool {
|
|
260
|
+
forwardMessage()
|
|
261
|
+
return true
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
**Return value:** Return `true` if the action was performed, `false` if not applicable.
|
|
267
|
+
|
|
268
|
+
---
|
|
269
|
+
|
|
270
|
+
## UIAccessibilityCustomRotor - Custom Navigation
|
|
271
|
+
|
|
272
|
+
Creates new items in VoiceOver's rotor for app-specific navigation (e.g., jump between headings, unread items, errors).
|
|
273
|
+
|
|
274
|
+
```swift
|
|
275
|
+
class ArticleViewController: UIViewController {
|
|
276
|
+
var headings: [Heading] = []
|
|
277
|
+
|
|
278
|
+
override func viewDidLoad() {
|
|
279
|
+
super.viewDidLoad()
|
|
280
|
+
accessibilityCustomRotors = [makeHeadingRotor(), makeBookmarkRotor()]
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
private func makeHeadingRotor() -> UIAccessibilityCustomRotor {
|
|
284
|
+
UIAccessibilityCustomRotor(name: "Headings") { [weak self] predicate in
|
|
285
|
+
guard let self = self else { return nil }
|
|
286
|
+
|
|
287
|
+
let currentIndex = self.headings.firstIndex { $0.view == predicate.currentItem.targetElement as? UIView }
|
|
288
|
+
let nextIndex: Int
|
|
289
|
+
|
|
290
|
+
switch predicate.searchDirection {
|
|
291
|
+
case .next:
|
|
292
|
+
nextIndex = (currentIndex.map { $0 + 1 }) ?? 0
|
|
293
|
+
case .previous:
|
|
294
|
+
nextIndex = currentIndex.map { $0 - 1 } ?? self.headings.count - 1
|
|
295
|
+
@unknown default:
|
|
296
|
+
return nil
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
guard nextIndex >= 0, nextIndex < self.headings.count else { return nil }
|
|
300
|
+
let heading = self.headings[nextIndex]
|
|
301
|
+
return UIAccessibilityCustomRotorItemResult(targetElement: heading.view, targetRange: nil)
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
---
|
|
308
|
+
|
|
309
|
+
## Notifications - Announcements and Focus
|
|
310
|
+
|
|
311
|
+
### Post an Announcement
|
|
312
|
+
|
|
313
|
+
```swift
|
|
314
|
+
// Simple string announcement
|
|
315
|
+
UIAccessibility.post(notification: .announcement, argument: "Message sent")
|
|
316
|
+
|
|
317
|
+
// Attributed string for priority control (iOS 17+)
|
|
318
|
+
let announcement = NSAttributedString(
|
|
319
|
+
string: "Emergency alert",
|
|
320
|
+
attributes: [.accessibilitySpeechQueueAnnouncement: true]
|
|
321
|
+
)
|
|
322
|
+
UIAccessibility.post(notification: .announcement, argument: announcement)
|
|
323
|
+
```
|
|
324
|
+
|
|
325
|
+
### Screen Changed — Full Focus Reset
|
|
326
|
+
|
|
327
|
+
Post when the entire screen content changes (e.g., modal presented, tab switched).
|
|
328
|
+
|
|
329
|
+
```swift
|
|
330
|
+
// Focus moves to the first element
|
|
331
|
+
UIAccessibility.post(notification: .screenChanged, argument: nil)
|
|
332
|
+
|
|
333
|
+
// Focus moves to a specific view
|
|
334
|
+
UIAccessibility.post(notification: .screenChanged, argument: confirmButton)
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### Layout Changed — Partial Update
|
|
338
|
+
|
|
339
|
+
Post when part of the layout changes (section expands, items load, error appears).
|
|
340
|
+
|
|
341
|
+
```swift
|
|
342
|
+
UIAccessibility.post(notification: .layoutChanged, argument: errorLabel)
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### Page Scrolled
|
|
346
|
+
|
|
347
|
+
```swift
|
|
348
|
+
UIAccessibility.post(notification: .pageScrolled, argument: "Page 3 of 10")
|
|
349
|
+
```
|
|
350
|
+
|
|
351
|
+
### Observing Status Changes
|
|
352
|
+
|
|
353
|
+
```swift
|
|
354
|
+
NotificationCenter.default.addObserver(
|
|
355
|
+
self,
|
|
356
|
+
selector: #selector(voiceOverStatusChanged),
|
|
357
|
+
name: UIAccessibility.voiceOverStatusDidChangeNotification,
|
|
358
|
+
object: nil
|
|
359
|
+
)
|
|
360
|
+
|
|
361
|
+
@objc func voiceOverStatusChanged() {
|
|
362
|
+
// Update UI if needed — but avoid branching core logic on VoiceOver status
|
|
363
|
+
}
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
---
|
|
367
|
+
|
|
368
|
+
## UIAccessibilityReadingContent
|
|
369
|
+
|
|
370
|
+
For views that display long-form text (e-book readers, document viewers). Enables VoiceOver's "Read All" and line-by-line navigation.
|
|
371
|
+
|
|
372
|
+
```swift
|
|
373
|
+
class BookPageView: UIView, UIAccessibilityReadingContent {
|
|
374
|
+
var lines: [String] = []
|
|
375
|
+
|
|
376
|
+
func accessibilityLineNumber(for point: CGPoint) -> Int {
|
|
377
|
+
return lineIndex(for: point)
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
func accessibilityContent(forLineNumber lineNumber: Int) -> String? {
|
|
381
|
+
guard lineNumber < lines.count else { return nil }
|
|
382
|
+
return lines[lineNumber]
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
func accessibilityFrame(forLineNumber lineNumber: Int) -> CGRect {
|
|
386
|
+
return UIAccessibility.convertToScreenCoordinates(
|
|
387
|
+
frameForLine(lineNumber), in: self
|
|
388
|
+
)
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
func accessibilityPageContent() -> String? {
|
|
392
|
+
return lines.joined(separator: " ")
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
---
|
|
398
|
+
|
|
399
|
+
## Modal Views
|
|
400
|
+
|
|
401
|
+
When a modal or alert is presented, VoiceOver must be prevented from reaching background content.
|
|
402
|
+
|
|
403
|
+
```swift
|
|
404
|
+
class ModalView: UIView {
|
|
405
|
+
override var accessibilityViewIsModal: Bool {
|
|
406
|
+
get { true }
|
|
407
|
+
set { }
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// When presenting:
|
|
412
|
+
func presentModal() {
|
|
413
|
+
let modal = ModalView()
|
|
414
|
+
view.addSubview(modal)
|
|
415
|
+
// VoiceOver now ignores everything behind modal
|
|
416
|
+
UIAccessibility.post(notification: .screenChanged, argument: modal.firstInteractiveElement)
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
// Support Escape to dismiss (VO two-finger Z)
|
|
420
|
+
override func accessibilityPerformEscape() -> Bool {
|
|
421
|
+
dismiss()
|
|
422
|
+
return true
|
|
423
|
+
}
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
---
|
|
427
|
+
|
|
428
|
+
## Custom Control Patterns
|
|
429
|
+
|
|
430
|
+
### Toggle / Checkbox
|
|
431
|
+
|
|
432
|
+
```swift
|
|
433
|
+
class AccessibleCheckbox: UIControl {
|
|
434
|
+
var isChecked: Bool = false {
|
|
435
|
+
didSet { accessibilityValue = isChecked ? "On" : "Off" }
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
override var isAccessibilityElement: Bool { get { true } set {} }
|
|
439
|
+
override var accessibilityLabel: String? { get { title } set {} }
|
|
440
|
+
override var accessibilityTraits: UIAccessibilityTraits {
|
|
441
|
+
get { isChecked ? [.button, .selected] : .button }
|
|
442
|
+
set {}
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
// Or use .toggleButton trait (iOS 17+)
|
|
446
|
+
}
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
### Custom Slider
|
|
450
|
+
|
|
451
|
+
```swift
|
|
452
|
+
class CustomSlider: UIView {
|
|
453
|
+
var value: Float = 0.5
|
|
454
|
+
var minValue: Float = 0
|
|
455
|
+
var maxValue: Float = 1
|
|
456
|
+
|
|
457
|
+
override var accessibilityTraits: UIAccessibilityTraits { get { .adjustable } set {} }
|
|
458
|
+
override var accessibilityValue: String? {
|
|
459
|
+
get { "\(Int(value * 100)) percent" }
|
|
460
|
+
set {}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
override func accessibilityIncrement() {
|
|
464
|
+
value = min(maxValue, value + 0.05)
|
|
465
|
+
UIAccessibility.post(notification: .layoutChanged, argument: self)
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
override func accessibilityDecrement() {
|
|
469
|
+
value = max(minValue, value - 0.05)
|
|
470
|
+
UIAccessibility.post(notification: .layoutChanged, argument: self)
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
```
|
|
474
|
+
|
|
475
|
+
### `accessibilityActivate()` — Custom Activation
|
|
476
|
+
|
|
477
|
+
Called when VoiceOver user double-taps. Useful when the normal tap behavior differs from the accessibility action.
|
|
478
|
+
|
|
479
|
+
```swift
|
|
480
|
+
override func accessibilityActivate() -> Bool {
|
|
481
|
+
// Show expanded detail view instead of just toggling
|
|
482
|
+
showDetailPanel()
|
|
483
|
+
return true // true = handled, false = pass to normal tap handler
|
|
484
|
+
}
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
---
|
|
488
|
+
|
|
489
|
+
## NSAttributedString Accessibility Attributes
|
|
490
|
+
|
|
491
|
+
Apply per-character accessibility attributes for rich text.
|
|
492
|
+
|
|
493
|
+
```swift
|
|
494
|
+
let string = NSMutableAttributedString(string: "Error: Invalid password")
|
|
495
|
+
string.addAttributes([
|
|
496
|
+
.accessibilitySpeechPitch: 0.5, // lower pitch
|
|
497
|
+
.accessibilitySpeechQueueAnnouncement: true, // queue, don't interrupt
|
|
498
|
+
.accessibilitySpeechSpellOut: false,
|
|
499
|
+
.accessibilitySpeechLanguage: "en-US"
|
|
500
|
+
], range: NSRange(location: 0, length: string.length))
|
|
501
|
+
|
|
502
|
+
label.attributedText = string
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
---
|
|
506
|
+
|
|
507
|
+
## Common Mistakes
|
|
508
|
+
|
|
509
|
+
| Mistake | Fix |
|
|
510
|
+
|---|---|
|
|
511
|
+
| Container `isAccessibilityElement = true` alongside `accessibilityElements` | Set `isAccessibilityElement = false` on containers that expose children |
|
|
512
|
+
| `accessibilityFrame` in local coordinates | Always convert: `UIAccessibility.convertToScreenCoordinates(rect, in: view)` |
|
|
513
|
+
| Forgetting to invalidate cached `accessibilityElements` | Nil out cache and post `.layoutChanged` when data changes |
|
|
514
|
+
| Missing `accessibilityIncrement`/`Decrement` on `.adjustable` trait | `.adjustable` trait requires both methods |
|
|
515
|
+
| No `accessibilityPerformEscape()` on custom modals | Implement to support two-finger Z gesture and Escape key |
|
|
516
|
+
| Using `notification: .screenChanged` for partial updates | Use `.layoutChanged` for partial; `.screenChanged` for full screen replacement |
|
|
517
|
+
| `accessibilityViewIsModal` on wrong view | Set on the outermost modal view, not a child |
|
|
518
|
+
| No announcement after async state change | Post `.layoutChanged` or `.announcement` after network/async operations complete |
|
|
519
|
+
| Labels in `UIAccessibilityElement` not updated after layout change | Rebuild elements array and nil cache when bounds change |
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# WCAG 2.2 → iOS/SwiftUI/UIKit Mapping
|
|
2
|
+
|
|
3
|
+
Maps WCAG 2.2 Level A and AA success criteria to native platform APIs. Covers iOS, macOS, watchOS, tvOS, and visionOS. Based on WCAG 2.2 and WCAG2ICT (mobile application guidance).
|
|
4
|
+
|
|
5
|
+
**Scope:** Level A and AA only — these are the standard compliance targets. Level AAA criteria are noted where native frameworks provide support.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. Perceivable
|
|
10
|
+
|
|
11
|
+
### 1.1 Text Alternatives
|
|
12
|
+
|
|
13
|
+
| SC | Level | Requirement | Platform API |
|
|
14
|
+
|---|---|---|---|
|
|
15
|
+
| 1.1.1 Non-text Content | A | Text alternative for non-text content | SwiftUI: `.accessibilityLabel(_:)`, `.accessibilityHidden(true)` for decorative; UIKit: `accessibilityLabel`, `isAccessibilityElement = false` |
|
|
16
|
+
|
|
17
|
+
### 1.2 Time-based Media
|
|
18
|
+
|
|
19
|
+
| SC | Level | Requirement | Platform API |
|
|
20
|
+
|---|---|---|---|
|
|
21
|
+
| 1.2.1 Audio-only / Video-only | A | Alternative for prerecorded media | Provide transcript; use `AVPlayerViewController` |
|
|
22
|
+
| 1.2.2 Captions (Prerecorded) | A | Captions for prerecorded audio in video | `AVPlayerViewController` (auto-enables captions); `AVMediaCharacteristic.legible` |
|
|
23
|
+
| 1.2.3 Audio Description or Alternative | A | Audio description for prerecorded video | `AVMediaCharacteristic.describesVideoForAccessibility` |
|
|
24
|
+
| 1.2.4 Captions (Live) | AA | Captions for live audio in video | App-provided live captions/transcriptions integrated into the streaming experience|
|
|
25
|
+
| 1.2.5 Audio Description (Prerecorded) | AA | Audio description for prerecorded video | `AVPlayerViewController` + audio description track |
|
|
26
|
+
|
|
27
|
+
### 1.3 Adaptable
|
|
28
|
+
|
|
29
|
+
| SC | Level | Requirement | Platform API |
|
|
30
|
+
|---|---|---|---|
|
|
31
|
+
| 1.3.1 Info and Relationships | A | Programmatic structure matches visual | SwiftUI: `.accessibilityElement(children:)`, `.accessibilityAddTraits(.isHeader)`, `Section`, `NavigationStack`; UIKit: `UIAccessibilityTraits`, `accessibilityContainerType` |
|
|
32
|
+
| 1.3.2 Meaningful Sequence | A | Correct reading order | SwiftUI: `.accessibilitySortPriority(_:)`, layout order; UIKit: `accessibilityElements` array order |
|
|
33
|
+
| 1.3.3 Sensory Characteristics | A | Don't rely solely on shape, size, position, or sound | Combine visual cues with text labels and accessibility labels |
|
|
34
|
+
| 1.3.4 Orientation | AA | Content works in portrait and landscape | Support both orientations via Auto Layout / SwiftUI adaptive layout; lock only when essential (e.g., camera) |
|
|
35
|
+
| 1.3.5 Identify Input Purpose | AA | Programmatic purpose for input fields | UIKit: `textContentType` (`.emailAddress`, `.password`, etc.); SwiftUI: `.textContentType(_:)`, `.keyboardType(_:)` |
|
|
36
|
+
|
|
37
|
+
### 1.4 Distinguishable
|
|
38
|
+
|
|
39
|
+
| SC | Level | Requirement | Platform API |
|
|
40
|
+
|---|---|---|---|
|
|
41
|
+
| 1.4.1 Use of Color | A | Color is not the only visual indicator | Add shape, icon, or text alongside color; check with `@Environment(\.accessibilityDifferentiateWithoutColor)` |
|
|
42
|
+
| 1.4.2 Audio Control | A | Mechanism to pause/stop/control audio | Standard playback controls; respect silent mode |
|
|
43
|
+
| 1.4.3 Contrast (Minimum) | AA | 4.5:1 text, 3:1 large text | Semantic colors: `Color(.label)`, `Color(.secondaryLabel)`; check with Accessibility Inspector contrast checker; respond to `@Environment(\.colorSchemeContrast)` |
|
|
44
|
+
| 1.4.4 Resize Text | AA | Text resizable to 200% without loss | SwiftUI: `.font(.body)` text styles, `@ScaledMetric`; UIKit: `UIFontMetrics`, `adjustsFontForContentSizeCategory = true`; test with Dynamic Type Variants in Canvas |
|
|
45
|
+
| 1.4.5 Images of Text | AA | Use real text, not images of text | Use `Text` views with styling instead of rendered text images |
|
|
46
|
+
| 1.4.10 Reflow | AA | Content reflows at narrow widths | SwiftUI: `ViewThatFits` (iOS 16+), adaptive stacks; UIKit: Auto Layout with proper constraints |
|
|
47
|
+
| 1.4.11 Non-text Contrast | AA | 3:1 for UI components and graphics | Borders, icons, focus indicators against their backgrounds; use Accessibility Inspector |
|
|
48
|
+
| 1.4.12 Text Spacing | AA | Support adjusted spacing | Use system text styles — they respect user settings automatically |
|
|
49
|
+
| 1.4.13 Content on Hover/Focus | AA | Dismissible, hoverable, persistent | Ensure `.popover()` / `.help()` content stays visible when pointer moves into it, is dismissible via Escape, and persists until dismissed; avoid custom hover-triggered UI that vanishes on pointer move |
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## 2. Operable
|
|
54
|
+
|
|
55
|
+
### 2.1 Keyboard Accessible
|
|
56
|
+
|
|
57
|
+
| SC | Level | Requirement | Platform API |
|
|
58
|
+
|---|---|---|---|
|
|
59
|
+
| 2.1.1 Keyboard | A | All functionality via keyboard | Full Keyboard Access: every element reachable via Tab; SwiftUI: `.focusable()`, `FocusState`; UIKit: `canBecomeFocused`, `UIKeyCommand` |
|
|
60
|
+
| 2.1.2 No Keyboard Trap | A | Keyboard focus can always move away | Ensure Escape dismisses modals; SwiftUI: `.sheet()` handles this; UIKit: implement `accessibilityPerformEscape()` |
|
|
61
|
+
| 2.1.4 Character Key Shortcuts | A | Single-key shortcuts can be remapped/disabled | Avoid single-character key shortcuts; use modifier keys (Cmd+, Ctrl+) |
|
|
62
|
+
|
|
63
|
+
### 2.2 Enough Time
|
|
64
|
+
|
|
65
|
+
| SC | Level | Requirement | Platform API |
|
|
66
|
+
|---|---|---|---|
|
|
67
|
+
| 2.2.1 Timing Adjustable | A | Users can extend time limits | Provide timeout warnings and extensions; no auto-advancing without user control |
|
|
68
|
+
| 2.2.2 Pause, Stop, Hide | A | Auto-updating content can be paused | Provide pause controls; respect `@Environment(\.accessibilityReduceMotion)` |
|
|
69
|
+
|
|
70
|
+
### 2.3 Seizures and Physical Reactions
|
|
71
|
+
|
|
72
|
+
| SC | Level | Requirement | Platform API |
|
|
73
|
+
|---|---|---|---|
|
|
74
|
+
| 2.3.1 Three Flashes | A | No content flashes > 3 times/second | Avoid flashing content; gate with `accessibilityReduceMotion` |
|
|
75
|
+
|
|
76
|
+
### 2.4 Navigable
|
|
77
|
+
|
|
78
|
+
| SC | Level | Requirement | Platform API |
|
|
79
|
+
|---|---|---|---|
|
|
80
|
+
| 2.4.1 Bypass Blocks | A | Skip repeated content | SwiftUI: use `NavigationStack`, `TabView` for structure; UIKit: `accessibilityContainerType = .semanticGroup` |
|
|
81
|
+
| 2.4.2 Page Titled | A | Screens have descriptive titles | SwiftUI: `.navigationTitle(_:)`; UIKit: `title` property on `UIViewController` |
|
|
82
|
+
| 2.4.3 Focus Order | A | Logical focus/navigation order | SwiftUI: `.accessibilitySortPriority(_:)`, layout order; UIKit: `accessibilityElements` array |
|
|
83
|
+
| 2.4.4 Link Purpose | A | Purpose of links clear from context | Use descriptive button/link labels; avoid "Click here" |
|
|
84
|
+
| 2.4.5 Multiple Ways | AA | Multiple ways to reach content | Tab bar + search + navigation hierarchy |
|
|
85
|
+
| 2.4.6 Headings and Labels | AA | Descriptive headings and labels | SwiftUI: `.accessibilityAddTraits(.isHeader)`; UIKit: `UIAccessibilityTraits.header` |
|
|
86
|
+
| 2.4.7 Focus Visible | AA | Keyboard focus indicator visible | System provides default focus rings; do not suppress them with `.focusEffectDisabled(true)`; AppKit: only set `NSView.focusRingType = .none` when drawing a custom focus ring or when space is insufficient for the default ring |
|
|
87
|
+
| 2.4.11 Focus Not Obscured (Minimum) | AA | Focused element not fully hidden | Ensure modals/overlays don't cover the focused element; use `.accessibilityViewIsModal` |
|
|
88
|
+
|
|
89
|
+
### 2.5 Input Modalities
|
|
90
|
+
|
|
91
|
+
| SC | Level | Requirement | Platform API |
|
|
92
|
+
|---|---|---|---|
|
|
93
|
+
| 2.5.1 Pointer Gestures | A | Single-pointer alternative to multi-touch | Provide button alternatives for pinch/rotate gestures; `.accessibilityAction` for custom gestures |
|
|
94
|
+
| 2.5.2 Pointer Cancellation | A | Down-event doesn't trigger action | Use `touchUpInside` (UIKit default), not `touchDown`; SwiftUI `Button` handles this automatically |
|
|
95
|
+
| 2.5.3 Label in Name | A | Accessible name contains visible text | Voice Control: `.accessibilityInputLabels` must match or contain visible text |
|
|
96
|
+
| 2.5.4 Motion Actuation | A | Alternative to device motion | Don't require shake/tilt; provide on-screen button alternative |
|
|
97
|
+
| 2.5.7 Dragging Movements | AA | Single-pointer alternative to drag | Provide button-based reorder; `.accessibilityAction(named: "Move Up") { … }`; `.accessibilityDragPoint` / `.accessibilityDropPoint` |
|
|
98
|
+
| 2.5.8 Target Size (Minimum) | AA | Touch targets ≥ 24×24 CSS px (44×44pt recommended) | SwiftUI: `.frame(minWidth: 44, minHeight: 44)`; UIKit: ensure `accessibilityFrame` ≥ 44×44pt; the Human Interface Guidelines recommend 44×44pt |
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## 3. Understandable
|
|
103
|
+
|
|
104
|
+
### 3.1 Readable
|
|
105
|
+
|
|
106
|
+
| SC | Level | Requirement | Platform API |
|
|
107
|
+
|---|---|---|---|
|
|
108
|
+
| 3.1.1 Language of Page | A | Language of content is programmatic | Set app language in Info.plist `CFBundleDevelopmentRegion`; per-view: SwiftUI `.environment(\.locale, …)` |
|
|
109
|
+
| 3.1.2 Language of Parts | AA | Language of parts identified | `NSAttributedString` with `.accessibilitySpeechLanguage`; SwiftUI: `.accessibilitySpeechLanguage(_:)` |
|
|
110
|
+
|
|
111
|
+
### 3.2 Predictable
|
|
112
|
+
|
|
113
|
+
| SC | Level | Requirement | Platform API |
|
|
114
|
+
|---|---|---|---|
|
|
115
|
+
| 3.2.1 On Focus | A | No unexpected changes on focus | Don't trigger navigation or state changes on focus alone |
|
|
116
|
+
| 3.2.2 On Input | A | No unexpected changes on input | Confirm before submitting; don't auto-navigate on picker selection |
|
|
117
|
+
| 3.2.3 Consistent Navigation | AA | Consistent navigation across screens | Use standard `TabView`, `NavigationStack` patterns |
|
|
118
|
+
| 3.2.4 Consistent Identification | AA | Same function = same label | Use consistent `.accessibilityLabel` across screens for same action |
|
|
119
|
+
| 3.2.6 Consistent Help | A | Help mechanism in consistent location | Place help in Settings or consistent toolbar position |
|
|
120
|
+
|
|
121
|
+
### 3.3 Input Assistance
|
|
122
|
+
|
|
123
|
+
| SC | Level | Requirement | Platform API |
|
|
124
|
+
|---|---|---|---|
|
|
125
|
+
| 3.3.1 Error Identification | A | Errors identified and described | Post `AccessibilityNotification.Announcement` for errors; use `.accessibilityLabel` on error text |
|
|
126
|
+
| 3.3.2 Labels or Instructions | A | Input fields have labels | SwiftUI: `TextField("Email", …)`; UIKit: `accessibilityLabel` on `UITextField` |
|
|
127
|
+
| 3.3.3 Error Suggestion | AA | Suggest corrections for errors | Provide actionable error messages; use `.textContentType` for autofill suggestions |
|
|
128
|
+
| 3.3.4 Error Prevention (Legal/Financial) | AA | Reversible, verified, or confirmed | Confirm destructive actions; provide undo; review before submit |
|
|
129
|
+
| 3.3.7 Redundant Entry | A | Don't re-ask for previously entered info | Use Keychain, AutoFill, and state management to avoid re-entry |
|
|
130
|
+
| 3.3.8 Accessible Authentication (Minimum) | AA | No cognitive function test for auth | Support passkeys, biometrics (`LAContext`), password managers; avoid CAPTCHAs |
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## 4. Robust
|
|
135
|
+
|
|
136
|
+
### 4.1 Compatible
|
|
137
|
+
|
|
138
|
+
| SC | Level | Requirement | Platform API |
|
|
139
|
+
|---|---|---|---|
|
|
140
|
+
| 4.1.2 Name, Role, Value | A | All UI components have accessible name, role, value | SwiftUI: `.accessibilityLabel`, `.accessibilityValue`, `.accessibilityAddTraits`; UIKit: `accessibilityLabel`, `accessibilityTraits`, `accessibilityValue` |
|
|
141
|
+
| 4.1.3 Status Messages | AA | Status changes announced without focus | SwiftUI: `AccessibilityNotification.Announcement(_:).post()`; UIKit: `UIAccessibility.post(notification: .announcement, argument:)` |
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Quick Lookup: WCAG SC → Nutrition Label
|
|
146
|
+
|
|
147
|
+
| Nutrition Label | Primary WCAG SC |
|
|
148
|
+
|---|---|
|
|
149
|
+
| VoiceOver | 1.1.1, 1.3.1, 1.3.2, 2.4.3, 2.4.6, 4.1.2 |
|
|
150
|
+
| Voice Control | 2.5.3, 2.5.8, 2.1.1 |
|
|
151
|
+
| Larger Text | 1.4.4, 1.4.10, 1.4.12 |
|
|
152
|
+
| Dark Interface | 1.4.3, 1.4.11 |
|
|
153
|
+
| Differentiate Without Color | 1.4.1, 1.4.11 |
|
|
154
|
+
| Sufficient Contrast | 1.4.3, 1.4.11 |
|
|
155
|
+
| Reduced Motion | 2.2.2, 2.3.1 |
|
|
156
|
+
| Captions | 1.2.2, 1.2.4 |
|
|
157
|
+
| Audio Descriptions | 1.2.3, 1.2.5 |
|
|
158
|
+
|
|
159
|
+
---
|
|
160
|
+
|
|
161
|
+
## Mobile-Specific Notes (from WCAG2ICT)
|
|
162
|
+
|
|
163
|
+
- **Touch targets**: WCAG 2.5.8 specifies 24×24 CSS pixels minimum. Human Interface Guidelines recommend 44×44pt — use that stricter standard.
|
|
164
|
+
- **Orientation**: Support all orientations unless essential to the experience (1.3.4). Don't lock to portrait unless the feature requires it (e.g., camera viewfinder).
|
|
165
|
+
- **Text resize**: iOS Dynamic Type satisfies 1.4.4. Test at all sizes including Accessibility sizes — use Xcode Canvas Dynamic Type Variants.
|
|
166
|
+
- **Drag alternatives**: 2.5.7 requires single-pointer alternatives to drag. Provide button-based reordering, `.accessibilityAction(named:)`, or `.accessibilityDragPoint` / `.accessibilityDropPoint`.
|
|
167
|
+
- **Authentication**: 3.3.8 is new in WCAG 2.2. Support biometrics (`Face ID`, `Touch ID`), passkeys, and password autofill to avoid cognitive function tests.
|