---
title: RemoteMediaSessionRepresentable
framework: nowplaying
role: symbol
role_heading: Protocol
path: nowplaying/remotemediasessionrepresentable
---

# RemoteMediaSessionRepresentable

A session that plays remotely, potentially across multiple devices.

## Declaration

```swift
@MainActor protocol RemoteMediaSessionRepresentable : Identifiable
```

## Mentioned in

Publishing remote media sessions

## Overview

Overview Conform to this protocol to represent playback happening outside of the current device. This object is expected to interact with a remote device, and thus may require some form of remote connection that you set up on initialization. Your session provides metadata and supported commands, as well as the list of devices playing in this session. It also handles volume changes and commands targeting the remote session. important: The system may request updates about this session via update(_:), where an instance of a Codable type your app defines passes into the function. Your implementation uses the passed Attributes instance to update the model objects from your session, which informs the system of any metadata or command changes. Your app donates remote sessions to the system in two ways: from the main app, or through push notifications. See RemoteMediaSession for the in-app API to donate a remote session. The following example shows a basic implementation: // A struct representing the current playback information from a remote device. struct PlayerSnapshot: Codable {   let trackId: String   let title: String   let artist: String   let album: String   let duration: Double   let elapsedTime: Double   let timestamp: Date   let isPlaying: Bool   let playingDevices: [PlayingDevice] }

struct PlayingDevice: Codable {   let id: String   let name: String   let volume: Float }

@Observable class RemotePlayerModel {     var server: ServerConnection     var snapshot: PlayerSnapshot }

class MySession: RemoteMediaSessionRepresentable {     struct Attributes: RemoteMediaSessionAttributes {         let id: String         var snapshot: PlayerSnapshot     }

let id: String     var remotePlayer: RemotePlayerModel

var devices: [MediaDevice] {         remotePlayer.snapshot.playingDevices.map { device in             MediaDevice(                 id: device.id,                 name: device.name,                 type: .speaker,                 capabilities: [                     .absoluteVolume(device.volume) { newLevel in                         // Communicate with an external server to issue the volume change                         try await remotePlayer.server.setVolume(newLevel, forDevice: device.id)                     }                 ]             )         }     }

var content: (any MediaContentRepresentable)? {         let snapshot = remotePlayer.snapshot         return MusicContent(             id: snapshot.trackId,             songTitle: snapshot.title,             artistName: snapshot.artist,             albumName: snapshot.album,             type: .audio,             duration: .finite(snapshot.duration),             artwork: Artwork(id: snapshot.trackId) { size in                 let data = await remotePlayer.server.loadArtworkData(for: snapshot.trackId, size: size)                 return try ArtworkRepresentation(data: data)             }         )     }

var playbackSnapshot: MediaPlaybackSnapshot {         let snapshot = remotePlayer.snapshot         if snapshot.isPlaying {             return MediaPlaybackSnapshot(                 state: .playing(rate: 1.0),                 elapsedTime: snapshot.elapsedTime,                 timestamp: snapshot.timestamp             )         } else {             return MediaPlaybackSnapshot(                 state: .paused,                 elapsedTime: snapshot.elapsedTime,                 timestamp: snapshot.timestamp             )         }     }

var commands: [MediaCommand] {[         .play {           // Communicate with an external server to issue the command           try await remotePlayer.server.play()         },         .pause {           try await remotePlayer.server.pause()         },         // … more supported commands …     ]}

func update(_ attributes: Attributes) {       // Incorporate the incoming attributes into your existing model       remotePlayer.update(with: attributes)     }     // … }

## Topics

### Associated Types

- [Attributes](nowplaying/remotemediasessionrepresentable/attributes.md)

### Instance Properties

- [commands](nowplaying/remotemediasessionrepresentable/commands.md)
- [content](nowplaying/remotemediasessionrepresentable/content.md)
- [devices](nowplaying/remotemediasessionrepresentable/devices.md)
- [id](nowplaying/remotemediasessionrepresentable/id.md)
- [playbackSnapshot](nowplaying/remotemediasessionrepresentable/playbacksnapshot.md)
- [pushToken](nowplaying/remotemediasessionrepresentable/pushtoken.md)
- [pushTokenUpdates](nowplaying/remotemediasessionrepresentable/pushtokenupdates.md)

### Instance Methods

- [update(_:)](nowplaying/remotemediasessionrepresentable/update(_:).md)

## Relationships

### Inherits From

- [Identifiable](swift/identifiable.md)

## See Also

### Remote sessions

- [Publishing remote media sessions](nowplaying/publishing-remote-media-sessions.md)
- [RemoteMediaSession](nowplaying/remotemediasession.md)
- [RemoteMediaSessionExtension](nowplaying/remotemediasessionextension.md)
- [RemoteMediaSessionExtensionConfiguration](nowplaying/remotemediasessionextensionconfiguration.md)
- [RemoteMediaSessionAttributes](nowplaying/remotemediasessionattributes.md)
- [RemoteMediaSessionError](nowplaying/remotemediasessionerror.md)
- [MediaDevice](nowplaying/mediadevice.md)
