CtrlK
BlogDocsLog inGet started
Tessl Logo

dpearson2699/swift-ios-skills

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

71

Quality

89%

Does it follow best practices?

Impact

No eval scenarios have been run

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

CHANGELOG.md

README.md

tile.json