-
Conheça o framework NowPlaying
Confira em primeira mão o framework NowPlaying, um framework Swift que conecta a reprodução de mídia do seu app às interfaces do sistema, como a Tela de Bloqueio, a Central de Controle, a Dynamic Island e o CarPlay. Descubra como publicar o estado de reprodução e responder aos comandos utilizando uma API observável. Explore sessões de reprodução remota, um novo recurso que permite ao seu app representar a mídia em reprodução em dispositivos externos e trazer controles completos de reprodução para essas mesmas interfaces do sistema.
Capítulos
- 0:00 - Introduction
- 1:08 - Media sessions
- 5:03 - Remote media sessions
- 10:31 - Media sharing extensions
Recursos
-
Buscar neste vídeo...
-
-
1:57 - Existing PlayerModel implementation
import Observation @Observable final class PlayerModel { let player: SoundPlayer var sound: Sound { player.currentSound } init(player: SoundPlayer) { self.player = player } } -
2:06 - Adopt MediaSessionRepresentable
import NowPlaying extension PlayerModel: MediaSessionRepresentable { var id: String { "ambient-sound-session" } var content: (any MediaContentRepresentable)? { return GenericContent( id: sound.id, title: sound.name, subtitle: sound.description, type: .audio, duration: .live, artwork: Artwork(id: sound.id) { size in let data = try await self.artworkData(size: size) return try ArtworkRepresentation(data: data) } ) } var playbackSnapshot: MediaPlaybackSnapshot? { MediaPlaybackSnapshot( state: player.isPlaying ? .playing() : .paused ) } var commands: [MediaCommand] {[ .play { self.player.play() }, .pause { self.player.pause() }, .previous { self.player.previous() }, .next { self.player.next() } ]} } -
4:31 - MediaSession initialization
import NowPlaying struct PlayerController { let player: SoundPlayer let model: PlayerModel let session: MediaSession<PlayerModel> init() { self.player = SoundPlayer() self.model = PlayerModel(player: player) self.session = MediaSession(model) } } -
6:42 - App extension entry point
import ExtensionFoundation import NowPlaying @main final class SampleAppExtension: @MainActor RemoteMediaSessionExtension { var configuration: some AppExtensionConfiguration { RemoteMediaSessionExtensionConfiguration(extension: self) } var extensionPoint: AppExtensionPoint { AppExtensionPoint.Identifier(host: "com.apple.nowplaying", name: "remote-media") } func session(_ state: RemotePlayerState) async throws -> RemotePlayerModel { RemotePlayerModel(state: state) } } -
7:23 - Existing RemotePlayerModel implementation
import Observation @Observable @MainActor final class RemotePlayerModel { let client: ServerClient var state: RemotePlayerState init(state: RemotePlayerState) { self.client = ServerClient(sessionID: state.sessionID) self.state = state } } -
7:40 - Adopt RemoteMediaSessionRepresentable in app extension
import NowPlaying extension RemotePlayerModel: @MainActor RemoteMediaSessionRepresentable { var id: String { state.sessionID } var content: (any MediaContentRepresentable)? { GenericContent( id: state.sound.id, title: state.sound.name, subtitle: state.sound.description, type: .audio, duration: .live, artwork: Artwork(id: state.sound.id) { size in let data = try await self.artworkData(size: size) return try ArtworkRepresentation(data: data) } ) } var playbackSnapshot: MediaPlaybackSnapshot? { MediaPlaybackSnapshot( state: state.isPlaying ? .playing() : .paused ) } var commands: [MediaCommand] {[ .play { try await self.client.send(.play) }, .pause { try await self.client.send(.pause) }, .previous { try await self.client.send(.previous) }, .next { try await self.client.send(.next) } ]} var devices: [MediaDevice] { state.devices.map { device in MediaDevice( id: device.id, name: device.name, type: .speaker, capabilities: [ .absoluteVolume(device.volume) { volume in // send volume change to server } ] ) } } func update(_ state: RemotePlayerState) { self.state = state } }
-
-
- 0:00 - Introduction
Discover the Now Playing system experience, available across all Apple platforms. It allows apps to surface currently playing media info on system surfaces like the Lock Screen, Dynamic Island, and CarPlay.
- 1:08 - Media sessions
Learn how to use the media sessions API to bring audio or video from your app into the system's Now Playing experience by adopting the MediaSessionRepresentable protocol.
- 5:03 - Remote media sessions
Discover how to extend playback control to devices like smart speakers by adopting RemoteMediaSessionRepresentable and utilizing Apple Push Notification service (APNs).
- 10:31 - Media sharing extensions
Find out how Media Sharing Extensions simplify routing media from iPhone to other devices by leveraging the system device picker without needing to embed additional SDKs.