Play/Pause callback not getting called when using MPRemoteCommandCenter
Asked Answered
F

3

6

I am building a music player app, and everything is working fine. I have been using the system music player so far, but now want to switch over to use an application music player instead, and that's where I'm running into problems - for the life of me I can't figure out how to get my play/pause callback to be called from the iOS control center. Here's the code I'm using in my main view controller:

override func viewDidLoad() {
    super.viewDidLoad()

    self.musicPlayer = MPMusicPlayerController.applicationMusicPlayer()

    self.registerForMediaPlayerNotifications()
    UIApplication.sharedApplication().beginReceivingRemoteControlEvents()

    let commandCenter = MPRemoteCommandCenter.sharedCommandCenter()

    commandCenter.previousTrackCommand.enabled = false
    commandCenter.previousTrackCommand.addTarget(self, action: "previousTrack")
    commandCenter.nextTrackCommand.enabled = false
    commandCenter.nextTrackCommand.addTarget(self, action: "nextTrack")
    commandCenter.togglePlayPauseCommand.enabled = true
    commandCenter.togglePlayPauseCommand.addTarget(self, action: "playOrPauseMusic")
    commandCenter.pauseCommand.addTarget(self, action: "playOrPauseMusic")
    commandCenter.pauseCommand.enabled = true
    commandCenter.playCommand.addTarget(self, action: "playOrPauseMusic")
    commandCenter.playCommand.enabled = true

    [...]
}


func previousTrack() {
}

func nextTrack() {
}

func playOrPauseMusic() {
   print("playOrPause")
}
Familiarity answered 21/1, 2016 at 13:51 Comment(7)
The only thing I can think of, is that your object does not exist anymore when the callback comes. Do you store the object somewhere?Volution
You mean the commandCenter object? No I'm not storing this anywhere, as I assumed it would be some global shared instance for which I only need the reference to set targets / enable/disable etc. I can give this a try though...Familiarity
No, I mean self, the object that contains this code. Put a breakpoint in its dealloc to see whether it gets cleaned up.Volution
Oh.. Well this code is in my main view controller. The play/pause doesn't even work when swiping up to show the command center while this main view is displayed, so I guess it should definitely still exist at this point.Familiarity
you have no need to call beginReceivingRemoteControlEvents when using MPRemoteCommandCenter.Saran
I have the same issue. Did you manage to solve it??Flawed
Nope, I ended up using the system music player insteadFamiliarity
S
5

I had this same issue and noticed that the callback for togglePlayPauseCommand wasn't getting called, but previousTrackCommand was. So after some experimentation I got this working by removing togglePlayPauseCommand and instead indiviudally implementing the inline callbacks for playCommand and pauseCommand - please note that using custom selectors weren't working, they had to be the inline callbacks.

let commandCenter = MPRemoteCommandCenter.shared()

commandCenter.playCommand.addTarget { (commandEvent) -> MPRemoteCommandHandlerStatus in
    moviePlayer.prepareToPlay()
    moviePlayer.play()
    return MPRemoteCommandHandlerStatus.success
}

commandCenter.pauseCommand.addTarget { (commandEvent) -> MPRemoteCommandHandlerStatus in
    moviePlayer.pause()
    return MPRemoteCommandHandlerStatus.success
}
Swatow answered 17/9, 2016 at 17:54 Comment(0)
L
1

Try adding Required background modes to the Info.plist like this:

Info.plist screenshot

Lawry answered 11/3, 2016 at 5:55 Comment(0)
D
-4

place your code in viewDidApper.

Damask answered 28/4, 2016 at 15:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.