View in English

  • Apple Developer
    • 시작하기

    시작하기 탐색

    • 개요
    • 알아보기
    • Apple Developer Program

    알림 받기

    • 최신 뉴스
    • Hello Developer
    • 플랫폼

    플랫폼 탐색

    • Apple 플랫폼
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    • App Store

    피처링

    • 디자인
    • 배포
    • 게임
    • 액세서리
    • 웹
    • 홈
    • CarPlay
    • 기술

    기술 탐색

    • 개요
    • Xcode
    • Swift
    • SwiftUI

    피처링

    • 손쉬운 사용
    • 앱 인텐트
    • Apple Intelligence
    • 게임
    • 머신 러닝 및 AI
    • 보안
    • Xcode Cloud
    • 커뮤니티

    커뮤니티 탐색

    • 개요
    • Apple과의 만남 이벤트
    • 커뮤니티 주도 이벤트
    • 개발자 포럼
    • 오픈 소스

    피처링

    • WWDC
    • Swift Student Challenge
    • 개발자 이야기
    • App Store 어워드
    • Apple 디자인 어워드
    • 문서

    문서 탐색

    • 문서 라이브러리
    • 기술 개요
    • 샘플 코드
    • 휴먼 인터페이스 가이드라인
    • 비디오

    릴리즈 노트

    • 피처링 업데이트
    • iOS
    • iPadOS
    • macOS
    • watchOS
    • visionOS
    • tvOS
    • Xcode
    • 다운로드

    다운로드 탐색

    • 모든 다운로드
    • 운영 체제
    • 애플리케이션
    • 디자인 리소스

    피처링

    • Xcode
    • TestFlight
    • 서체
    • SF Symbols
    • Icon Composer
    • 지원

    지원 탐색

    • 개요
    • 도움말
    • 개발자 포럼
    • 피드백 지원
    • 문의하기

    피처링

    • 계정 도움말
    • 앱 심사 지침
    • App Store Connect 도움말
    • 새로 추가될 요구 사항
    • 계약 및 지침
    • 시스템 상태
  • 빠른 링크

    • 이벤트
    • 뉴스
    • 포럼
    • 샘플 코드
    • 비디오
 

비디오

메뉴 열기 메뉴 닫기
  • 컬렉션
  • 전체 비디오
  • 소개

더 많은 비디오

  • 소개
  • 요약
  • 코드
  • NowPlaying 프레임워크 만나 보기

    앱의 미디어 재생을 잠금 화면, 제어 센터, Dynamic Island, CarPlay와 같은 시스템 표면에 연결하는 Swift 프레임워크인 NowPlaying을 처음으로 살펴보세요. 관찰 가능 API를 사용하여 재생 상태를 게시하고 명령에 응답하는 방법을 알아보세요. 앱이 외부 기기에서 재생 중인 미디어를 표시하고 동일한 시스템 표면에 전체 재생 제어 항목을 적용할 수 있도록 해 주는 새로운 기능인 원격 재생 세션을 살펴보세요.

    챕터

    • 0:00 - Introduction
    • 1:08 - Media sessions
    • 5:03 - Remote media sessions
    • 10:31 - Media sharing extensions

    리소스

    • Routing media to third-party devices
    • Publishing remote media sessions
    • Publishing media sessions
    • Setting up a remote notification server
      • HD 비디오
      • SD 비디오
  • 비디오 검색…
    • 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.

Developer Footer

  • 비디오
  • WWDC26
  • NowPlaying 프레임워크 만나 보기
  • 메뉴 열기 메뉴 닫기
    • iOS
    • iPadOS
    • macOS
    • tvOS
    • visionOS
    • watchOS
    메뉴 열기 메뉴 닫기
    • Swift
    • SwiftUI
    • Swift Playground
    • TestFlight
    • Xcode
    • Xcode Cloud
    • SF Symbols
    메뉴 열기 메뉴 닫기
    • 손쉬운 사용
    • 액세서리
    • Apple Intelligence
    • 앱 확장 프로그램
    • App Store
    • 오디오 및 비디오(영문)
    • 증강 현실
    • 디자인
    • 배포
    • 교육
    • 서체(영문)
    • 게임
    • 건강 및 피트니스
    • 앱 내 구입
    • 현지화
    • 지도 및 위치
    • 머신 러닝 및 AI
    • 오픈 소스(영문)
    • 보안
    • Safari 및 웹(영문)
    메뉴 열기 메뉴 닫기
    • 문서(영문)
    • 튜토리얼
    • 다운로드
    • 포럼(영문)
    • 비디오
    메뉴 열기 메뉴 닫기
    • 지원 문서
    • 문의하기
    • 버그 보고
    • 시스템 상태(영문)
    메뉴 열기 메뉴 닫기
    • Apple Developer
    • App Store Connect
    • 인증서, 식별자 및 프로파일(영문)
    • 피드백 지원
    메뉴 열기 메뉴 닫기
    • Apple Developer Program
    • Apple Developer Enterprise Program
    • App Store Small Business Program
    • MFi Program(영문)
    • Mini Apps Partner Program
    • News Partner Program(영문)
    • Video Partner Program(영문)
    • Security Bounty Program(영문)
    • Security Research Device Program(영문)
    메뉴 열기 메뉴 닫기
    • Apple과의 만남
    • Apple Developer Center
    • App Store 어워드(영문)
    • Apple 디자인 어워드
    • Apple Developer Academy(영문)
    • WWDC
    최신 뉴스 읽기.
    Apple Developer 앱 받기.
    Copyright © 2026 Apple Inc. 모든 권리 보유.
    약관 개인정보 처리방침 계약 및 지침