How to get notified when iOS music app changes state

121 Views Asked by At

I have tried every possible method to subscribe and I'm not getting any notifications

let musicPlayer = MPMusicPlayerController.systemMusicPlayer
let appMusicPlayer = MPMusicPlayerController.applicationMusicPlayer
let queuePlayer = MPMusicPlayerController.applicationQueuePlayer

func subscribe() {


    MPMediaLibrary.requestAuthorization { _ in }      

    musicPlayer.beginGeneratingPlaybackNotifications()
    appMusicPlayer.beginGeneratingPlaybackNotifications()
    queuePlayer.beginGeneratingPlaybackNotifications()

    NotificationCenter.default.addObserver(forName: .MPMusicPlayerControllerPlaybackStateDidChange, object: musicPlayer, queue: .main) { [weak self] notification in
        debugPrint("hello")
    }
    
    NotificationCenter.default.addObserver(forName: .MPMusicPlayerControllerPlaybackStateDidChange, object: appMusicPlayer, queue: .main) { [weak self] notification in
        debugPrint("hello")
    }
    
    NotificationCenter.default.addObserver(forName: .MPMusicPlayerControllerPlaybackStateDidChange, object: queuePlayer, queue: .main) { [weak self] notification in
        debugPrint("hello")
    }

    NotificationCenter.default.addObserver(
        self,
        selector: #selector(playbackStateChanged(_:)),
        name: .MPMusicPlayerControllerPlaybackStateDidChange,
        object: musicPlayer
    )

    NotificationCenter.default.addObserver(
        self,
        selector: #selector(playbackStateChanged(_:)),
        name: .MPMusicPlayerControllerPlaybackStateDidChange,
        object: appMusicPlayer
    )

    NotificationCenter.default.addObserver(
        self,
        selector: #selector(playbackStateChanged(_:)),
        name: .MPMusicPlayerControllerPlaybackStateDidChange,
        object: queuePlayer
    )

}

1

There are 1 best solutions below

6
Ginder Singh On BEST ANSWER

Mostly likely you are running app on simulator but go through this checklist if you are not.

  • Add "NSAppleMusicUsageDescription" to your .plist file with string value which describes why you need access to Media player framework.

  • Use sample code

    
    
    import SwiftUI
    import MediaPlayer
    
    struct ContentView: View {
        var body: some View {
            VStack {
                Image(systemName: "globe")
                    .imageScale(.large)
                    .foregroundStyle(.tint)
                Text("SetupMusic").onTapGesture {
                    setup()
                }
            }
            .padding()
        }
    }
    
    private func setup() {
        debugPrint("Requesting access")
        MPMediaLibrary.requestAuthorization { permission in
            debugPrint("Setting up music player")
            let musicPlayer = MPMusicPlayerController.systemMusicPlayer
            musicPlayer.beginGeneratingPlaybackNotifications()
            debugPrint("Initial State: \(musicPlayer.playbackState)")
            NotificationCenter.default.addObserver(forName: .MPMusicPlayerControllerPlaybackStateDidChange, object: musicPlayer, queue: .main) {  notification in
                debugPrint("State changed to \(musicPlayer.playbackState)")
            }
        }
    }
    
    #Preview {
        ContentView()
    }
    
    
    
  1. Run app on real iOS device. Simulator does not support MPMediaPlayer framework.
  2. Hit button to allow for permission.
  3. Once granted you should get initial state. (Stopped/Paused)
  4. Go to system music app and play something on radio.
  5. Launch app again you should see state change to Playing
  6. Swipe down for notifications and pause music and state will change to Paused
  7. Event will only be fired if app is in foreground state.