What's New / Media, Audio & Capture

What's new in AVKit

+24 New~10 DeprecatediOS · visionOS

AVKit provides view controllers and supporting types for playing video and audio through the system playback interface, including transport controls, media selection, and metadata display.

The 27 SDK adds 24 APIs and deprecates 10. The new surface is an AVInterface protocol family for driving playback UI: AVInterfaceControllable, AVInterfacePlaybackControllable, AVInterfaceTimeControllable, AVInterfaceVolumeControllable, AVInterfaceMediaSelectionControllable, and AVInterfaceMetadataProviding, with supporting types AVInterfacePlaybackState, AVInterfaceSeekCapabilities, AVInterfaceMetadata (members include AlbumArtwork, isAudioOnly, presentationSize), and TransitionGroup. The deprecations all land on AVInterfaceMediaSelectionOptionSource: extendedLanguageTagTemp, several init overloads, url, and contentType.

New

24
protocol

AVInterfaceControllable

NewiOS
public protocol AVInterfaceControllable : AVInterfaceMediaSelectionControllable, AVInterfaceMetadataProviding, AVInterfacePlaybackControllable, AVInterfaceTimeControllable, AVInterfaceVolumeControllable

A comprehensive protocol that provides complete media control and information for playback, timeline navigation, audio/subtitle selection, volume control, and metadata access.

This protocol consolidates all media source capabilities into a single interface, enabling rich media experiences with full control over playback state, timeline interactions, and content metadata.

Declaration
@MainActor public protocol AVInterfaceControllable : AVInterfaceMediaSelectionControllable, AVInterfaceMetadataProviding, AVInterfacePlaybackControllable, AVInterfaceTimeControllable, AVInterfaceVolumeControllable {
}
protocol

AVInterfaceMediaSelectionControllable

NewiOS
public protocol AVInterfaceMediaSelectionControllable : Observable

Provides audio and subtitle selection capabilities for media content.

Declaration
@MainActor public protocol AVInterfaceMediaSelectionControllable : Observable {

    /// Currently selected audio track for playback.
    @MainActor var currentAudioOption: AVInterfaceMediaSelectionOptionSource? { get set }

    /// Currently selected subtitle or caption track.
    @MainActor var currentLegibleOption: AVInterfaceMediaSelectionOptionSource? { get set }

    /// Array of available audio track options for selection.
    @MainActor var audioOptions: [AVInterfaceMediaSelectionOptionSource] { get }

    /// Array of available subtitle and caption track options.
    @MainActor var legibleOptions: [AVInterfaceMediaSelectionOptionSource] { get }
}
extension

AVInterfaceMediaSelectionOptionSource

NewiOS
extension AVInterfaceMediaSelectionOptionSource

Swift-specific extension for AVInterfaceMediaSelectionOptionSource.

Declaration
extension AVInterfaceMediaSelectionOptionSource {

    /// IETF BCP 47 language identifier represented as a `Locale.Language`.
    ///
    /// This standardized tag provides detailed language information including region, script, and variants.
    /// Returns `nil` for language-neutral content such as music-only audio tracks, sound effects, or visual-only subtitles without spoken content.
    @available(iOS, introduced: 27.0, deprecated: 27.0, renamed: "language", message: "Use language instead")
    @available(tvOS, unavailable)
    @available(visionOS, unavailable)
    public var extendedLanguageTagTemp: Locale.Language? { get }

    /// The language of this media selection option.
    ///
    /// This standardized tag provides detailed language information including region, script, and variants.
    /// Returns `nil` for language-neutral content such as music-only audio tracks, sound effects, or visual-only subtitles without spoken content.
    public var language: Locale.Language? { get }

    /// Creates a new media selection option.
    ///
    /// - Parameters:
    ///   - displayName: Human-readable name displayed in user interfaces.
    ///   - identifier: Unique system identifier for programmatic selection.
    ///   - extendedLanguageTag: IETF BCP 47 language identifier, or nil for language-neutral content.
    @available(iOS, introduced: 27.0, deprecated: 27.0, renamed: "init(displayName:identifier:extendedLanguageTagTemp:)", message: "Use init(displayName:identifier:extendedLanguageTagTemp:) instead")
    @available(tvOS, unavailable)
    @available(visionOS, unavailable)
    public convenience init(displayName: String, identifier: String, extendedLanguageTag: String?)

    /// Creates a new media selection option.
    ///
    /// - Parameters:
    ///   - displayName: Human-readable name displayed in user interfaces.
    ///   - identifier: Unique system identifier for programmatic selection.
    ///   - extendedLanguageTagTemp: IETF BCP 47 language identifier, or nil for language-neutral content.
    @available(iOS, introduced: 27.0, deprecated: 27.0, renamed: "init(displayName:identifier:language:)", message: "Use init(displayName:identifier:language:) instead")
    @available(tvOS, unavailable)
    @available(visionOS, unavailable)
    public convenience init(displayName: String, identifier: String, extendedLanguageTagTemp: Locale.Language? = nil)

    /// Creates a new media selection option.
    ///
    /// - Parameters:
    ///   - displayName: Human-readable name displayed in user interfaces.
    ///   - identifier: Unique system identifier for programmatic selection.
    ///   - language: The language of the media selection option, or nil for language-neutral content.
    public convenience init(displayName: String, identifier: String, language: Locale.Language? = nil)
}
struct

AVInterfaceMetadata

NewiOS
public struct AVInterfaceMetadata : Sendable, Hashable

A Swift-friendly structure representing media metadata.

This structure provides metadata information about media content including title, artwork, and content type. Use this to provide rich information for playback interfaces and system integrations.

Declaration
public struct AVInterfaceMetadata : Sendable, Hashable {

    @available(iOS, introduced: 27.0, deprecated: 27.0, renamed: "AVInterfaceAlbumArtwork", message: "Use AVInterfaceAlbumArtwork instead")
    @available(tvOS, unavailable)
    @available(visionOS, unavailable)
    public typealias AlbumArtwork = AVInterfaceAlbumArtwork

    /// Describes the type of media content and its display characteristics.
    ///
    /// Use `MediaMode` to indicate whether content is audio-only or includes video,
    /// and to provide the natural presentation size for video content.
    public enum MediaMode : Sendable, Hashable {

        /// The content contains only audio with no video component.
        case audioOnly

        /// The content contains video with the specified natural pixel dimensions.
        ///
        /// - Parameter presentationSize: The natural pixel dimensions of the video content,
        ///   used for aspect ratio calculations and layout.
        case video(presentationSize: CGSize)

        /// Returns a Boolean value indicating whether two values are equal.
        ///
        /// Equality is the inverse of inequality. For any values `a` and `b`,
        /// `a == b` implies that `a != b` is `false`.
        ///
        /// - Parameters:
        ///   - lhs: A value to compare.
        ///   - rhs: Another value to compare.
        public static func == (a: AVInterfaceMetadata.MediaMode, b: AVInterfaceMetadata.MediaMode) -> Bool

        /// Hashes the essential components of this value by feeding them into the
        /// given hasher.
        ///
        /// Implement this method to conform to the `Hashable` protocol. The
        /// components used for hashing must be the same as the components compared
        /// in your type's `==` operator implementation. Call `hasher.combine(_:)`
        /// with each of these components.
        ///
        /// - Important: In your implementation of `hash(into:)`,
        ///   don't call `finalize()` on the `hasher` instance provided,
        ///   or replace it with a different instance.
        ///   Doing so may become a compile-time error in the future.
        ///
        /// - Parameter hasher: The hasher to use when combining the components
        ///   of this instance.
        public func hash(into hasher: inout Hasher)

        /// The hash value.
        ///
        /// Hash values are not guaranteed to be equal across different executions of
        /// your program. Do not save hash values to use during a future execution.
        ///
        /// - Important: `hashValue` is deprecated as a `Hashable` requirement. To
        ///   conform to `Hashable`, implement the `hash(into:)` requirement instead.
        ///   The compiler provides an implementation for `hashValue` for you.
        public var hashValue: Int { get }
    }

    /// The mode describing whether this content is audio-only or includes video.
    public var mediaMode: AVInterfaceMetadata.MediaMode

    /// Indicates whether the content is audio-only (no video component).
    @available(iOS, introduced: 27.0, deprecated: 27.0, message: "Use mediaMode instead")
    @available(tvOS, unavailable)
    @available(visionOS, unavailable)
    public var isAudioOnly: Bool

    /// The natural pixel dimensions of the video content for display purposes.
    ///
    /// This represents the encoded size of the video stream and can be used to determine aspect ratio and optimal presentation layout.
    /// For audio-only content, this value is `.zero`.
    @available(iOS, introduced: 27.0, deprecated: 27.0, message: "Use mediaMode instead")
    @available(tvOS, unavailable)
    @available(visionOS, unavailable)
    public var presentationSize: CGSize

    /// Primary title or name of the media content.
    public var title: String?

Truncated.

protocol

AVInterfaceMetadataProviding

NewiOS
public protocol AVInterfaceMetadataProviding : Observable

Provides metadata information about media content including title, artwork, and content type.

Declaration
@MainActor public protocol AVInterfaceMetadataProviding : Observable {

    /// The metadata object containing information about the media content.
    @MainActor var metadata: AVInterfaceMetadata { get }
}
protocol

AVInterfacePlaybackControllable

NewiOS
public protocol AVInterfacePlaybackControllable : Observable

Provides playback control and state management for media content.

Declaration
@MainActor public protocol AVInterfacePlaybackControllable : Observable {

    /// Indicates whether the media source is ready for playback operations.
    @MainActor var isReady: Bool { get }

    /// Indicates whether the media is currently playing.
    @MainActor var isPlaying: Bool { get set }

    /// Indicates whether the media source is currently buffering content.
    @MainActor var isBuffering: Bool { get }

    /// The current playback speed multiplier.
    @MainActor var playbackSpeed: Float { get set }

    /// The scanning speed multiplier used during fast-forward or rewind operations.
    @MainActor var scanSpeed: Float { get set }

    /// The current operational state of the interface source.
    @MainActor var state: AVInterfacePlaybackState { get set }

    /// The supported timeline navigation operations.
    @MainActor var supportedSeekCapabilities: AVInterfaceSeekCapabilities { get }

    /// Indicates whether the content contains live streaming content.
    @MainActor var containsLiveStreamingContent: Bool { get }

    /// Error information when the source encounters a playback failure.
    @MainActor var playbackError: (any Error)? { get }
}
enum

AVInterfacePlaybackState

NewiOS
public enum AVInterfacePlaybackState : Int, @unchecked Sendable
Declaration
public enum AVInterfacePlaybackState : Int, @unchecked Sendable {

    /// Indicates the source is in a normal state.
    case normal = 0

    /// Indicates the source is scanning forward or backward at an accelerated rate.
    case scanning = 1

    /// Indicates the source is being scrubbed by user interaction with the timeline.
    case scrubbing = 2
}
struct

AVInterfaceSeekCapabilities

NewiOS
public struct AVInterfaceSeekCapabilities : OptionSet, @unchecked Sendable
Declaration
public struct AVInterfaceSeekCapabilities : OptionSet, @unchecked Sendable {

    public init(rawValue: UInt)

    /// The source supports forward scanning at accelerated rates for fast-forward operations. Enables rapid progression through content at speeds greater than normal playback.
    public static var scanForward: AVInterfaceSeekCapabilities { get }

    /// The source supports backward scanning at accelerated rates for rewind operations. Enables rapid reverse progression through content at speeds greater than normal playback.
    public static var scanBackward: AVInterfaceSeekCapabilities { get }

    /// The source supports seeking to specific time positions for precise navigation. Enables jumping directly to any arbitrary point within the seekable time ranges.
    public static var seek: AVInterfaceSeekCapabilities { get }
}
protocol

AVInterfaceTimeControllable

NewiOS
public protocol AVInterfaceTimeControllable : Observable

Provides time control and navigation capabilities for media content.

Declaration
@MainActor public protocol AVInterfaceTimeControllable : Observable {

    /// The time range representing the total duration and bounds of the media content.
    @MainActor var timeRange: CMTimeRange { get }

    /// The current playback position within the media time.
    @MainActor var currentPlaybackPosition: CMTime { get set }

    /// Segments representing different content types within the timeline.
    @MainActor var segments: [AVInterfaceTimelineSegment] { get }

    /// The segment containing the current playback position.
    @MainActor var currentSegment: AVInterfaceTimelineSegment { get }

    /// Time ranges within the timeline where seeking operations are permitted.
    @MainActor var seekableTimeRanges: [CMTimeRange]? { get }
}
protocol

AVInterfaceVolumeControllable

NewiOS
public protocol AVInterfaceVolumeControllable : Observable

Provides volume and audio muting control for media content.

Declaration
@MainActor public protocol AVInterfaceVolumeControllable : Observable {

    /// Indicates whether the media contains audio tracks.
    @MainActor var hasAudio: Bool { get }

    /// Controls whether audio output is temporarily silenced.
    @MainActor var isMuted: Bool { get set }

    /// The audio output level as a normalized value between 0.0 and 1.0.
    @MainActor var volume: Float { get set }
}
extension

AVPortalViewport

NewvisionOS
extension AVPortalViewport
Declaration
extension AVPortalViewport {

    public var aspectRatio: Double?
}
var

contentType

NewiOS
open var contentType: UTType? { get }

The uniform type identifier for the artwork image data.

init

init

NewiOS
public init(url: URL, contentType: UTType, size: CGSize)
var

url

NewiOS
open var url: URL? { get }

URL pointing to the album artwork image resource.

var

viewport

NewvisionOS
open var viewport: AVViewport { get }
struct

AVExperienceController.TransitionGroup

NewvisionOS
public struct TransitionGroup<ChildTransitionResult> : ~Copyable, ~Escapable where ChildTransitionResult : Sendable

A group of experience transitions that prepare concurrently and run simultaneously as a single visual transition.

Use withTransitionGroup(body:) to create a transition group. Add transitions using addTransition(operation:), and they perform together once all have been added and prepared.

Transitions in a group prepare concurrently, then perform their animations simultaneously, creating a single cohesive visual transition. Each transition completes with its own result, allowing you to handle individual successes and failures.

## Handle Failures

Individual transitions may fail during preparation or execution without affecting other transitions in the group.

Declaration
public struct TransitionGroup<ChildTransitionResult> : ~Copyable, ~Escapable where ChildTransitionResult : Sendable {

    /// Adds a transition to the group, suspending it until all transitions are ready to run together.
    ///
    /// Call ``transition(to:)`` on an ``AVExperienceController`` within the operation closure.
    /// The transition suspends until all transitions have been added to the group,
    /// then perform together with the others.
    ///
    /// ``withTransitionGroup(body:)`` includes the value you return from the closure in the order
    /// transitions were added.
    ///
    /// ```swift
    /// group.addTransition {
    ///     await controller.transition(to: .multiview)
    /// }
    /// ```
    ///
    /// - Parameter operation: A closure that performs a transition and returns a result.
    public mutating func addTransition(operation: sending @escaping @isolated(any) () async -> ChildTransitionResult)
}
func

AVExperienceController.withTransitionGroup

NewvisionOS
nonisolated(nonsending) public static func withTransitionGroup<ChildTransitionResult>(body: @_lifetime(0: copy 0) (inout AVExperienceController.TransitionGroup<ChildTransitionResult>) async -> Void) async -> [ChildTransitionResult] where ChildTransitionResult : Sendable

Coordinates multiple experience transitions to perform together as a single visual transition.

Use this method when you need to transition multiple AVExperienceController instances simultaneously, creating a smooth, coordinated animation.

All transitions prepare concurrently, then perform together once preparation completes. Individual transitions may succeed or fail independently — the group continues with successful transitions and collects results for all.

let results = await AVExperienceController.withTransitionGroup { group in
    for controller in controllers {
        group.addTransition {
            await controller.transition(to: .multiview)
        }
    }
}

// Check which transitions succeeded
for (index, result) in results.enumerated() {
    if case .reversed(let reason) = result {
        print("Controller \(index) failed: \(reason)")
    }
}

Parameters

body
A closure that adds transitions to the group using addTransition(operation:).

ReturnsAn array of transition results in the order transitions were added.

var

AVInterfaceMediaSelectionOptionSource.extendedLanguageTagTemp

NewiOS
public var extendedLanguageTagTemp: Locale.Language? { get }

IETF BCP 47 language identifier represented as a Locale.Language.

This standardized tag provides detailed language information including region, script, and variants. Returns nil for language-neutral content such as music-only audio tracks, sound effects, or visual-only subtitles without spoken content.

init

AVInterfaceMediaSelectionOptionSource.init

NewiOS
public convenience init(displayName: String, identifier: String, extendedLanguageTag: String?)

Creates a new media selection option.

Parameters

displayName
Human-readable name displayed in user interfaces.
identifier
Unique system identifier for programmatic selection.
extendedLanguageTag
IETF BCP 47 language identifier, or nil for language-neutral content.
init

AVInterfaceMediaSelectionOptionSource.init

NewiOS
public convenience init(displayName: String, identifier: String, extendedLanguageTagTemp: Locale.Language? = nil)

Creates a new media selection option.

Parameters

displayName
Human-readable name displayed in user interfaces.
identifier
Unique system identifier for programmatic selection.
extendedLanguageTagTemp
IETF BCP 47 language identifier, or nil for language-neutral content.
typealias

AVInterfaceMetadata.AlbumArtwork

NewiOS
public typealias AlbumArtwork = AVInterfaceAlbumArtwork
init

AVInterfaceMetadata.init

NewiOS
public init(isAudioOnly: Bool = false, presentationSize: CGSize = .zero, title: String? = nil, subtitle: String? = nil, albumArtworkRepresentations: [AVInterfaceAlbumArtwork] = [])

Creates a new metadata object.

Parameters

isAudioOnly
Whether the content is audio-only (default: false).
presentationSize
The natural pixel dimensions of the video content (default: .zero).
title
Primary title or name of the media content.
subtitle
Secondary descriptive text.
albumArtworkRepresentations
Array of available album artwork representations in various formats and sizes.
var

AVInterfaceMetadata.isAudioOnly

NewiOS
public var isAudioOnly: Bool

Indicates whether the content is audio-only (no video component).

var

AVInterfaceMetadata.presentationSize

NewiOS
public var presentationSize: CGSize

The natural pixel dimensions of the video content for display purposes.

This represents the encoded size of the video stream and can be used to determine aspect ratio and optimal presentation layout. For audio-only content, this value is .zero.

Deprecated

10
var

contentType

DeprecatediOS
open var contentType: UTType? { get }
DeprecatedcontentType is deprecated

The uniform type identifier for the artwork image data.

init

init

DeprecatediOS
public init(url: URL, contentType: UTType, size: CGSize)
DeprecatedUse artworkWithURL:contentType:size: instead
var

url

DeprecatediOS
open var url: URL? { get }
Deprecatedurl is deprecated

URL pointing to the album artwork image resource.

var

AVInterfaceMediaSelectionOptionSource.extendedLanguageTagTemp

DeprecatediOS
public var extendedLanguageTagTemp: Locale.Language? { get }
Deprecatedlanguage

IETF BCP 47 language identifier represented as a Locale.Language.

This standardized tag provides detailed language information including region, script, and variants. Returns nil for language-neutral content such as music-only audio tracks, sound effects, or visual-only subtitles without spoken content.

init

AVInterfaceMediaSelectionOptionSource.init

DeprecatediOS
public convenience init(displayName: String, identifier: String, extendedLanguageTag: String?)

Creates a new media selection option.

Parameters

displayName
Human-readable name displayed in user interfaces.
identifier
Unique system identifier for programmatic selection.
extendedLanguageTag
IETF BCP 47 language identifier, or nil for language-neutral content.
init

AVInterfaceMediaSelectionOptionSource.init

DeprecatediOS
public convenience init(displayName: String, identifier: String, extendedLanguageTagTemp: Locale.Language? = nil)

Creates a new media selection option.

Parameters

displayName
Human-readable name displayed in user interfaces.
identifier
Unique system identifier for programmatic selection.
extendedLanguageTagTemp
IETF BCP 47 language identifier, or nil for language-neutral content.
typealias

AVInterfaceMetadata.AlbumArtwork

DeprecatediOS
public typealias AlbumArtwork = AVInterfaceAlbumArtwork
DeprecatedAVInterfaceAlbumArtwork
init

AVInterfaceMetadata.init

DeprecatediOS
public init(isAudioOnly: Bool = false, presentationSize: CGSize = .zero, title: String? = nil, subtitle: String? = nil, albumArtworkRepresentations: [AVInterfaceAlbumArtwork] = [])

Creates a new metadata object.

Parameters

isAudioOnly
Whether the content is audio-only (default: false).
presentationSize
The natural pixel dimensions of the video content (default: .zero).
title
Primary title or name of the media content.
subtitle
Secondary descriptive text.
albumArtworkRepresentations
Array of available album artwork representations in various formats and sizes.
var

AVInterfaceMetadata.isAudioOnly

DeprecatediOS
public var isAudioOnly: Bool
DeprecatedUse mediaMode instead

Indicates whether the content is audio-only (no video component).

var

AVInterfaceMetadata.presentationSize

DeprecatediOS
public var presentationSize: CGSize
DeprecatedUse mediaMode instead

The natural pixel dimensions of the video content for display purposes.

This represents the encoded size of the video stream and can be used to determine aspect ratio and optimal presentation layout. For audio-only content, this value is .zero.

No APIs match your filter.

← More in Media, Audio & Capture