CtrlK
BlogDocsLog inGet started
Tessl Logo

dpearson2699/swift-ios-skills

Agent skills for iOS, iPadOS, Swift, SwiftUI, and modern Apple framework development.

80

Quality

100%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Advisory

Suggest reviewing before use

Overview
Quality
Evals
Security
Files

media-accessibility.mdskills/ios-accessibility/references/

Media Accessibility

Accessibility patterns for audio and video content using AVFoundation.

Contents

  • Closed Captions and Subtitles
  • SwiftUI VideoPlayer
  • Custom Player Controls

Closed Captions and Subtitles

AVMediaCharacteristic Tags

AVFoundation uses media characteristics to identify accessibility tracks:

Docs: AVMediaCharacteristic

CharacteristicPurpose
.transcribesSpokenDialogForAccessibilityCaptions/SDH — transcribes dialog for deaf or hard of hearing users
.describesMusicAndSoundForAccessibilityCaptions that include descriptions of music and sound effects
.describesVideoForAccessibilityAudio descriptions — narrates visual content for blind or low-vision users
.easyToReadSimplified captions for cognitive accessibility
.containsOnlyForcedSubtitlesSubtitles that display only when content differs from the device language
.languageTranslationSubtitles providing a language translation

Selecting Accessible Media

import AVFoundation

let asset = AVURLAsset(url: videoURL)
let group = try await asset.load(.mediaSelectionGroup(forMediaCharacteristic: .legible))

if let group {
    // Find the closed caption option
    let ccOptions = AVMediaSelectionGroup.mediaSelectionOptions(
        from: group.options,
        with: .transcribesSpokenDialogForAccessibility
    )

    if let ccOption = ccOptions.first {
        let playerItem = AVPlayerItem(asset: asset)
        playerItem.select(ccOption, in: group)
    }
}

Audio Descriptions

let adGroup = try await asset.load(.mediaSelectionGroup(forMediaCharacteristic: .audible))

if let adGroup {
    let adOptions = AVMediaSelectionGroup.mediaSelectionOptions(
        from: adGroup.options,
        with: .describesVideoForAccessibility
    )

    if let adOption = adOptions.first {
        playerItem.select(adOption, in: adGroup)
    }
}

System Accessibility Settings

AVPlayer automatically selects captioned/described tracks when the user enables these in Settings → Accessibility → Subtitles & Captioning. You don't need manual selection unless providing a custom media selection UI.

Check user preferences:

import MediaAccessibility

let captioningEnabled = MACaptionAppearanceIsDisplayedAutomatically(.user)

SwiftUI VideoPlayer

SwiftUI's VideoPlayer inherits AVPlayer's automatic accessibility track selection:

import AVKit
import SwiftUI

struct AccessibleVideoView: View {
    let player: AVPlayer

    var body: some View {
        VideoPlayer(player: player)
            .accessibilityLabel("Training video")
            .accessibilityHint("Double-tap to play or pause")
    }
}

Custom Player Controls

When building custom video controls, ensure:

  • Play/pause, seek, and volume controls are all focusable and labeled
  • Current time and duration are announced on focus changes
  • Captions toggle is available and labeled
  • Progress slider uses accessibilityValue to announce time position
  • Controls remain visible/accessible when captions overlay is active
Button(action: toggleCaptions) {
    Image(systemName: captionsEnabled ? "captions.bubble.fill" : "captions.bubble")
}
.accessibilityLabel(captionsEnabled ? "Captions on" : "Captions off")
.accessibilityHint("Toggles closed captions")

skills

.mcp.json

README.md

tile.json