<!--
{
  "availability" : [
    "iOS: 27.0.0 -",
    "iPadOS: 27.0.0 -",
    "macCatalyst: 27.0.0 -",
    "macOS: 27.0.0 -",
    "tvOS: 27.0.0 -",
    "visionOS: 27.0.0 -",
    "watchOS: 27.0.0 -"
  ],
  "documentType" : "symbol",
  "framework" : "NowPlaying",
  "identifier" : "/documentation/NowPlaying/MediaSessionRepresentable",
  "metadataVersion" : "0.1.0",
  "role" : "Protocol",
  "symbol" : {
    "kind" : "Protocol",
    "modules" : [
      "Now Playing"
    ],
    "preciseIdentifier" : "s:10NowPlaying25MediaSessionRepresentableP"
  },
  "title" : "MediaSessionRepresentable"
}
-->

# MediaSessionRepresentable

A protocol that provides content metadata, playback state, and commands for a Now Playing session.

```
@MainActor protocol MediaSessionRepresentable : Identifiable
```

## Overview

Conform to this protocol to provide the media content description, playback state, and
commands like [`play(_:)`](/documentation/NowPlaying/MediaCommand/play(_:)), [`pause(_:)`](/documentation/NowPlaying/MediaCommand/pause(_:)),
[`next(_:)`](/documentation/NowPlaying/MediaCommand/next(_:)), [`previous(_:)`](/documentation/NowPlaying/MediaCommand/previous(_:)), and more.

The framework observes your `@Observable` model and automatically updates the system’s
Now Playing interface when your properties change.

For more information, see [Publishing media sessions](/documentation/NowPlaying/publishing-media-sessions)

The following example shows a basic session representable:

```swift
@Observable
class PlayerModel: MediaSessionRepresentable {
    let id = "com.example.music"
    var currentTrack: Track?
    var isPlaying = false
    var currentTime: TimeInterval = 0

    var content: (any MediaContentRepresentable)? {
        guard let track = currentTrack else { return nil }
        return MusicContent(
            id: track.id,
            songTitle: track.title,
            artistName: track.artist,
            albumName: track.album,
            type: .audio,
            duration: .finite(track.duration),
            isExplicit: track.isExplicit,
            artwork: Artwork(id: track.artworkID) { size in
                let data = await self.loadArtworkData(with: size)
                return try ArtworkRepresentation(data: data)
            }
        )
    }

    var playbackSnapshot: MediaPlaybackSnapshot? {
        if isPlaying {
            return MediaPlaybackSnapshot(state: .playing(rate: 1.0), elapsedTime: currentTime, timestamp: .now)
        } else {
            return MediaPlaybackSnapshot(state: .paused, elapsedTime: currentTime, timestamp: .now)
        }
    }

    var commands: [MediaCommand] {[
        .play { await self.play() },
        .pause { await self.pause() },
        .next { await self.nextTrack() },
        .previous { await self.previousTrack() },
    ]}
}
```

## Topics

### Instance Properties

[`var commands: [MediaCommand]`](/documentation/NowPlaying/MediaSessionRepresentable/commands)

The commands supported by this session.

[`var content: (any MediaContentRepresentable)?`](/documentation/NowPlaying/MediaSessionRepresentable/content)

The content being played in this session.

[`var id: String`](/documentation/NowPlaying/MediaSessionRepresentable/id)

The unique identifier for this session.

[`var playbackSnapshot: MediaPlaybackSnapshot?`](/documentation/NowPlaying/MediaSessionRepresentable/playbackSnapshot)

The current playback state of this session.

## Relationships

### Inherits From

[`Identifiable`](/documentation/Swift/Identifiable)

---

Copyright &copy; 2026 Apple Inc. All rights reserved. | [Terms of Use](https://www.apple.com/legal/internet-services/terms/site.html) | [Privacy Policy](https://www.apple.com/privacy/privacy-policy)