iosswiftcontrol-center

How to use Stop button in iOS control center instead of pause button with swift


I want to build a radio app and so I would like to use the stop button instead of the pause button in the control center like Apple Radio does in the native music app :

enter image description here

Here is what I did in my RadioPlayer class :

private var shoutcastStream = NSURL(string: "http://shoutcast.com:PORT/;stream.mp3")

var playerItem:AVPlayerItem?
var player:AVPlayer?

let commandCenter = MPRemoteCommandCenter.sharedCommandCenter()

override init() {

    super.init()

    do {

        // Allow background audio
        try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback)
        do {
            try AVAudioSession.sharedInstance().setActive(true)
        } catch _ as NSError {

        }

        // Disable Next, Prev and Pause
        commandCenter.pauseCommand.enabled = false
        commandCenter.nextTrackCommand.enabled = false
        commandCenter.previousTrackCommand.enabled = false

        // Enable Play
        commandCenter.playCommand.enabled = true
        commandCenter.playCommand.addTarget(self, action: #selector(RadioPlayer.play))

        // Enable Stop
        commandCenter.stopCommand.enabled = true
        commandCenter.stopCommand.addTarget(self, action: #selector(RadioPlayer.stop))

    } catch _ as NSError {

    }
}

It's now working fine but the stop button isn't showing. Instead, I have the Pause button, which doesn't make sense for a radio player haha.

Note that in the above case, even if the control center is showing the pause button, nothing happens when pause button is pressed, because no target is attached to it (I attached it to the stopCommand).

So the question is: how to use that Stop button? Thank you.


Solution

  • EDIT: I think the "stop" command is only displayed when MPNowPlayingInfoPropertyIsLiveStream = true (available only from iOS 10) /: It does not matter if you disable the "pause" or "togglePlayPause" commands. From iOS 10, the "stop" command will be displayed if MPNowPlayingInfoPropertyIsLiveStream = true. You may need to handle the "pause" or the "togglePlayPause" command too (for earlier versions). Good luck!

    OK, I also had this doubt and did not find on the internet how to do what I wanted so I started reading more about MPRemoteCommandCenter and MPNowPlayingInfoCenter. I tried disabling all the buttons I did not use. Also, I read about MPNowPlayingInfoPropertyIsLiveStream and I share in this post in case anyone finds it useful (look at the comments in the code):

    Swift 3

    MPNowPlayingInfoCenter (for metadata):

    var songInfo = [:] as [String : Any]
    
    if NSClassFromString("MPNowPlayingInfoCenter") != nil {
    
                songInfo[MPMediaItemPropertyArtwork] = MPMediaItemArtwork(image: UIImage(named: "your_image_name")!)
                songInfo[MPMediaItemPropertyTitle] = "Title"
                songInfo[MPMediaItemPropertyArtist] = "Artist name"
    
                // If is a live broadcast, you can set a newest property (iOS 10+): MPNowPlayingInfoPropertyIsLiveStream indicating that is a live broadcast
                if #available(iOS 10.0, *) {
                    songInfo[MPNowPlayingInfoPropertyIsLiveStream] = true
                } else {
                    // Fallback on earlier versions
                }
    
                MPNowPlayingInfoCenter.default().nowPlayingInfo = songInfo
    
    } // end if MPNowPlayingInfoCenter
    

    MPRemoteCommandCenter:

    if #available(iOS 9.1, *) {
    
                let center = MPRemoteCommandCenter.shared()
    
                // Disable all buttons you will not use (including pause and togglePlayPause commands)
                [center.pauseCommand, center.togglePlayPauseCommand, center.nextTrackCommand, center.previousTrackCommand, center.changeRepeatModeCommand, center.changeShuffleModeCommand, center.changePlaybackRateCommand, center.seekBackwardCommand, center.seekForwardCommand, center.skipBackwardCommand, center.skipForwardCommand, center.changePlaybackPositionCommand, center.ratingCommand, center.likeCommand, center.dislikeCommand, center.bookmarkCommand].forEach {
                    $0.isEnabled = false
                }
    
                // For "play" command
                center.playCommand.addTarget { (commandEvent) -> MPRemoteCommandHandlerStatus in
                    // play the song here
                    return MPRemoteCommandHandlerStatus.success
                }
    
                // For "stop" command
                center.stopCommand.addTarget { (commandEvent) -> MPRemoteCommandHandlerStatus in
                    // stop the song here
                    return MPRemoteCommandHandlerStatus.success
                }
    
            } else {
                // Fallback on earlier versions
            }
    

    I have done. I hope I have helped you and others (: