Install
$ agentstack add skill-mwd1234-ios-agentic-skills-accessibility ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
SwiftUI Accessibility Audit
Audit the codebase for Apple HIG accessibility compliance. Covers VoiceOver, motion, vision, and interaction accessibility.
When to use this skill
- Before App Store submission (required for Accessibility Nutrition Labels)
- After adding new Views, custom controls, or animations
- When reviewing PRs with UI changes
- When the user asks to check accessibility
Quick Reference: HIG Requirements
| Category | Requirement | |----------|-------------| | VoiceOver | All interactive elements must have descriptive labels; images need alt text | | Reduce Motion | Animations must respect accessibilityReduceMotion; provide static alternatives | | Dynamic Type | Text must scale with system font size; use relative sizing | | Color/Contrast | Don't rely solely on color; maintain 4.5:1 contrast ratio | | Touch Targets | Minimum 44×44pt for all interactive elements |
Step 1: VoiceOver Labels Audit
1.1 Missing Labels on Interactive Elements
# Buttons without accessibility labels
rg --type swift -g '!*Tests*' 'Button\s*\{' YourApp/Views/ | head -20
# Images without accessibility labels (decorative should use accessibilityHidden)
rg --type swift -g '!*Tests*' 'Image\(' YourApp/Views/ | head -20
# Custom controls that may need labels
rg --type swift -g '!*Tests*' '\.onTapGesture|\.gesture\(' YourApp/Views/ | head -20
1.2 accessibilityHidden on Non-Decorative Images
# Find hidden images - verify they are truly decorative
rg --type swift -g '!*Tests*' -B2 -A2 '\.accessibilityHidden\(true\)' YourApp/Views/ | head -30
HIG Requirement: Only hide truly decorative images. Meaningful images (icons indicating state, informational graphics) must NOT be hidden.
1.3 Accessibility Element Grouping
# Check for intentional grouping - ensure labels are preserved
rg --type swift -g '!*Tests*' '\.accessibilityElement\(children:' YourApp/Views/
Verify: When using .accessibilityElement(children: .ignore) or .combine, ensure the parent has a proper .accessibilityLabel() that describes the grouped content.
1.4 Labels Using Technical/Internal Values
# rawValue in accessibility contexts (should use localizedName)
rg --type swift -g '!*Tests*' '\.accessibilityLabel.*\.rawValue|\.accessibilityValue.*\.rawValue' YourApp/Views/
1.5 Unlocalized Strings in Views (Affects VoiceOver)
# Text(verbatim:) and Text(.init()) bypass localization
rg --type swift -g '!*Tests*' 'Text\(verbatim:|Text\(\.init\(' YourApp/Views/
Fix: Use Text("string", comment:) for user-facing text so VoiceOver reads localized content.
Step 2: Reduce Motion & Transparency Audit
2.1 Animations Not Respecting Reduce Motion
# Animations that may need @Environment(\.accessibilityReduceMotion)
rg --type swift -g '!*Tests*' '\.animation\(|withAnimation|\.transition\(' YourApp/Views/ | head -30
# Check if Reduce Motion is being read
rg --type swift -g '!*Tests*' 'accessibilityReduceMotion' YourApp/
Fix Pattern:
@Environment(\.accessibilityReduceMotion) var reduceMotion
.animation(reduceMotion ? nil : .easeInOut, value: state)
2.2 Auto-Playing or Looping Animations
# Repeating animations
rg --type swift -g '!*Tests*' '\.repeatForever|\.repeat\(' YourApp/Views/
# Timer-driven animations
rg --type swift -g '!*Tests*' 'Timer\.publish|onReceive.*timer' YourApp/Views/
2.3 Reduce Transparency (Blurred/Transparent UI)
# Blur effects and materials that need solid alternatives
rg --type swift -g '!*Tests*' '\.blur\(|\.background\(\.ultraThinMaterial|\.background\(\.thinMaterial' YourApp/Views/
# Check if Reduce Transparency is being respected
rg --type swift -g '!*Tests*' 'accessibilityReduceTransparency' YourApp/
HIG Requirement: When accessibilityReduceTransparency is enabled, replace blur/transparency effects with solid backgrounds.
Step 3: Color & Contrast Audit
3.1 Color-Only Indicators
# Color-only status indicators (need shape/icon alternatives)
rg --type swift -g '!*Tests*' '\.foregroundColor\(.*\.red|\.green|\.yellow' YourApp/Views/
# Check for differentiate without color
rg --type swift -g '!*Tests*' 'accessibilityDifferentiateWithoutColor' YourApp/
HIG Requirement: When accessibilityDifferentiateWithoutColor is enabled, add icons, patterns, or text labels alongside color indicators.
Fix Pattern:
@Environment(\.accessibilityDifferentiateWithoutColor) var differentiateWithoutColor
HStack {
Circle().fill(isActive ? .green : .red)
if differentiateWithoutColor {
Image(systemName: isActive ? "checkmark" : "xmark")
}
}
3.2 Contrast Verification
Manual check:
- Run Accessibility Inspector in Xcode
- Check 4.5:1 ratio for normal text, 3:1 for large text
- Test in Light and Dark modes
Step 4: Dynamic Type Audit
4.1 Fixed Font Sizes
# Hardcoded font sizes (should use relative sizing)
rg --type swift -g '!*Tests*' '\.font\(\.system\(size:' YourApp/Views/ | head -20
# Custom fonts that may not scale
rg --type swift -g '!*Tests*' 'Font\.custom\(' YourApp/Views/
Fix: Use semantic fonts: .font(.body), .font(.headline)
4.2 dynamicTypeSize Restrictions
# Check for dynamicTypeSize limits (may prevent scaling)
rg --type swift -g '!*Tests*' '\.dynamicTypeSize\(' YourApp/Views/
Verify: If limiting Dynamic Type range, ensure it's for layout constraints only, not to prevent accessibility scaling.
4.3 minimumScaleFactor on Labels
# Labels that shrink text instead of wrapping
rg --type swift -g '!*Tests*' '\.minimumScaleFactor\(' YourApp/Views/
Verify: Acceptable for single-line constraints (e.g., tab bar labels), but prefer .lineLimit(nil) for body text.
4.4 Fixed Frame Heights (Clips Large Text)
# Fixed heights that may clip scaled text
rg --type swift -g '!*Tests*' '\.frame\(height:|\.frame\(.*height:' YourApp/Views/ | head -20
Fix: Use .frame(minHeight:) for text containers.
Step 5: Touch Target Audit
# Small touch targets
rg --type swift -g '!*Tests*' '\.frame\(width:\s*[0-3][0-9],' YourApp/Views/
# ContentShape for gesture areas
rg --type swift -g '!*Tests*' '\.contentShape\(' YourApp/Views/
HIG Requirement: All touch targets minimum 44×44pt. Use .contentShape() to expand hit areas.
Step 6: Watch App Audit
WATCH_DIR="YourApp Watch App"
# VoiceOver labels
rg --type swift '\.accessibilityLabel\(|\.accessibilityValue\(' "$WATCH_DIR/Views/"
# Reduce Motion
rg --type swift 'accessibilityReduceMotion|WKAccessibilityIsReduceMotionEnabled' "$WATCH_DIR/"
# Always On Display (AOD) - pause animations when dimmed
rg --type swift 'isLuminanceReduced' "$WATCH_DIR/"
watchOS Requirement: When isLuminanceReduced is true (Always On Display), pause animations and reduce visual complexity:
@Environment(\.isLuminanceReduced) var isLuminanceReduced
.animation(isLuminanceReduced ? nil : .default, value: state)
Step 7: Accessibility Inspector Verification
- Xcode > Open Developer Tool > Accessibility Inspector
- Run app in Simulator
- Audit each screen for missing labels, incorrect traits, contrast issues
Skip Patterns
#Preview { }blocks*Tests*/,*UITests*/folders- Decorative images (should have
.accessibilityHidden(true))
Output Format
| Category | Issues | Status | |----------|--------|--------| | VoiceOver labels | X | ✅/❌ | | accessibilityHidden audit | X | ✅/❌ | | Element grouping | X | ✅/❌ | | Reduce Motion | X | ✅/❌ | | Reduce Transparency | X | ✅/❌ | | Differentiate Without Color | X | ✅/❌ | | Dynamic Type | X | ✅/❌ | | Touch targets | X | ✅/❌ | | Watch app (incl. AOD) | X | ✅/❌ |
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: mwd1234
- Source: mwd1234/ios-agentic-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.