6
votes

I am testing this using iOS 10.2 on my actual iPhone 6s device.

I am playing streamed audio and am able to play/pause audio, skip tracks, etc. I also have enabled background modes and the audio plays in the background and continues through a playlist properly. The only issue I am having is getting the lock screen controls to show up. Nothing displays at all...

In viewDidLoad() of my MainViewController, right when my app launches, I call this...

 func setupAudioSession(){

   UIApplication.shared.beginReceivingRemoteControlEvents()


   do {
       try    AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, with: AVAudioSessionCategoryOptions.mixWithOthers)

       self.becomeFirstResponder()

       do {
           try AVAudioSession.sharedInstance().setActive(true)
                   print("AVAudioSession is Active")
       } catch let error as NSError {
                   print(error.localizedDescription)

       }
   } catch let error as NSError {
               print(error.localizedDescription)
   }
}

and then in my AudioPlayer class after I begin playing audio I call ...

func setupLockScreen(){
       let commandCenter = MPRemoteCommandCenter.shared()
       commandCenter.nextTrackCommand.isEnabled = true
       commandCenter.nextTrackCommand.addTarget(self, action:#selector(skipTrack))
       MPNowPlayingInfoCenter.default().nowPlayingInfo = [MPMediaItemPropertyTitle: "TESTING"]
}

When I lock my iPhone and then tap the power button again to go to the lock screen, the audio controls are not displayed at all. It is as if no audio is playing, I just see my normal background photo. Also no controls are displayed in the control panel (swiping up on home screen and then swiping left to where the music controls should be).

Is the issue because I am not using AVAudioPlayer or AVPlayer? But then how does, for example, Spotify get the lock screen controls to display using their own custom audio player? Thanks for any advice / help

3

3 Answers

8
votes

The issue turned out to be this line...

try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, with: AVAudioSessionCategoryOptions.duckOthers)

Once I changed it to

try AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, with: [])

everything worked fine. So it seems that passing in any argument for AVAudioSessionCategoryPlaybackOptions causes the lock screen controls to not display. I also tried passing in .mixWithOthers an that too caused the lock screen controls to not be displayed

0
votes

In Swift 4. This example is only to show the player on the lock screen and works with iOS 11. To know how to play auidio on the device you can follow this thread https://stackoverflow.com/a/47710809/1283517

import MediaPlayer
import AVFoundation

Declare player

var player : AVPlayer?

Now create a function

func setupLockScreen(){
        let commandCenter = MPRemoteCommandCenter.shared()
        commandCenter.nextTrackCommand.isEnabled = true
        commandCenter.togglePlayPauseCommand.addTarget(self, action: #selector(controlPause))
        MPNowPlayingInfoCenter.default().nowPlayingInfo = [MPMediaItemPropertyTitle: currentStation]
    }

now create a function for control play and pause event. I have created a BOOL "isPlaying" to determine the status of the player.

@objc func controlPause() {
        if isPlaying == true {
            player?.pause()
            isPlaying = false
        } else {
            player?.play()
            isPlaying = true
        }
    }

And ready. Now the player will be displayed on the lock screen

-2
votes

Yes, for the lock screen to work you need to use iOS APIs to play audio. Not sure how Spotify does it but they may be using a second audio session in parallel for this purpose and use the controls to control both. Your background handler (the singleton in my case) could start playing the second audio with 0 volume when it goes into background and stop it when in foreground. I haven't tested it myself but an option to try.