Search code examples
iosswiftswiftuimpmusicplayercontrollerapple-music

SwiftUI Trying to use MPMusicPlayerController and playbackState


I am fairly new to SwiftUI, and I am struggling to use the Apple Swift Documentation. I'm trying to get the current state of the now playing music, hopefully printing something like

paused

or

playing

And so here is the code that I've come up with.

import SwiftUI
import MediaPlayer
import AVKit

struct MusicView: View {
        
    @State var playbackState: MPMusicPlaybackState? = MPMusicPlayerController.systemMusicPlayer.playbackState

    @State var updater = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
    
    var body: some View {
        Text("Hello")
            .onAppear(){
                print(playbackState)
            }
            .onReceive(updater){_ in
                playbackState = MPMusicPlayerController.systemMusicPlayer.playbackState
                print(playbackState)
            }
    }
}

I'm finding it very confusing to use, and I don't understand why its constantly printing:

Optional(__C.MPMusicPlaybackState)

I understand why it's optional, but why can't I get it to print some kind of state? And any source code that I seem to find is from 9 years ago in Obj-C. At this point, any help would be appreciated.


Solution

  • Swift doesn't know how to translate that C enum into printable text for you. You could use a switch statement to print the values.

    You could also listen for NotificationCenter updates for the state changes rather than use the Timer.

    extension MPMusicPlaybackState {
        func printState() {
            print(self)
            switch self {
            case .interrupted:
                print("interrupted")
            case .stopped:
                print("stopped")
            case .playing:
                print("playing")
            case .paused:
                print("paused")
            case .seekingForward:
                print("seekingForward")
            case .seekingBackward:
                print("seekingBackward")
            @unknown default:
                break
            }
        }
    }
    
    struct MusicView: View {
            
        @State var playbackState: MPMusicPlaybackState? = MPMusicPlayerController.systemMusicPlayer.playbackState
        
        var body: some View {
            Text("Hello")
                .onAppear(){
                    playbackState?.printState()
                }
                .onReceive(NotificationCenter.default.publisher(for: .MPMusicPlayerControllerPlaybackStateDidChange)){ _ in
                    playbackState = MPMusicPlayerController.systemMusicPlayer.playbackState
                    playbackState?.printState()
                }
        }
    }