5

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")
}
dflachbart
  • 105
  • 1
  • 10
  • 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? – fishinear Jan 21 '16 at 14:43
  • 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... – dflachbart Jan 21 '16 at 15:11
  • No, I mean self, the object that contains this code. Put a breakpoint in its `dealloc` to see whether it gets cleaned up. – fishinear Jan 21 '16 at 15:45
  • 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. – dflachbart Jan 21 '16 at 15:52
  • you have no need to call beginReceivingRemoteControlEvents when using MPRemoteCommandCenter. – Moaz Saeed Jun 19 '16 at 19:40
  • I have the same issue. Did you manage to solve it?? – nadi9 Aug 05 '16 at 10:57
  • Nope, I ended up using the system music player instead – dflachbart Aug 08 '16 at 13:46

3 Answers3

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
}
Anconia
  • 3,888
  • 6
  • 36
  • 65
1

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

Info.plist screenshot

Tobi Nary
  • 4,566
  • 4
  • 30
  • 50
satoshin
  • 309
  • 3
  • 3
-4

place your code in viewDidApper.

NeoGER89
  • 412
  • 4
  • 16