1

I am building an app that uses the AVPlayer and is set up to operate with lock screen controls while the app is in the background. I have implemented the following appropriately:

[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];

[[AVAudioSession sharedInstance] setActive: YES error: &error];

and I have MPNowPlayingInfoCenter properly configured.

One bug I've encountered is that the lock screen's controls fail to work when I wish to resume playing after playing music from another app (for example, Spotify). To reproduce this bug, I begin playing audio from my app, where setActive is called when my AVPlayer plays. Then I switch to Spotify and play a song, where my audio dies down and pauses. After a few seconds, I switch back to my app and resume my audio. When I lock my device, and press buttons on my lock screen, I see my audio's information on the screen, but none of my controls are working like they should.

beginReceivingRemoteControlEvents is called at startup within my appDelegate's applicationDidBecomeActive

I do have endReceivingRemoteControlEvents in a dealloc method from my appDelegate (this is legacy code I've inherited), but that isn't called in this scenario.

EDIT: I forgot to note, I'm testing on an iPad running iOS11.4

EDIT 2: Sorry, I failed to mention that this worked fine before the update to iOS11.4

EDIT 3: I found the issue, it was a boolean flag buried in our legacy code that wasn't being reset

Jargen89
  • 480
  • 1
  • 6
  • 19

2 Answers2

1

We have a music player that is available in the store, so I wanted to give a try to your question.

After trying MyApp > Spotify > MyApp route you defined I could not reproduce the error. Info center buttons are working correctly.

We are calling beginReceivingRemoteControlEvents at applicationDidEnterBackground. We are also calling addTargetWithHandler at this point. And endReceivingRemoteControlEvents at applicationDidBecomeActive. Something like this:

- (void)applicationDidEnterBackground:(UIApplication *)application
{
  [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];

  MPRemoteCommandCenter *remoteCommandCenter = [MPRemoteCommandCenter sharedCommandCenter];

  [remoteCommandCenter.playCommand addTargetWithHandler:^MPRemoteCommandHandlerStatus (MPRemoteCommandEvent *event) {
    //....
  }];
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
  [[UIApplication sharedApplication] endReceivingRemoteControlEvents];
}

The nature of the MPRemoteCommandCenter is being used when your app is in the background.

The problem might be the order of things.

emrahgunduz
  • 1,404
  • 1
  • 13
  • 26
  • I don't know if the order of the calls is the problem, the app was working fine before the 11.4 update. – Jargen89 Jun 28 '18 at 18:56
  • 1
    You might want to try the problem with Apple’s example code. If the same is happening, it is a bug and you can report it. However as I said, our app is working fine. Here is the link to demo: https://developer.apple.com/library/archive/samplecode/MPRemoteCommandSample/Introduction/Intro.html – emrahgunduz Jun 28 '18 at 19:00
  • we don't have code directly related to the MPRemoteCommandCenter implemented, but we are handling UIEventSubtypeRemote events. I found the error in logic in another layer. Thanks for pointing the way – Jargen89 Jun 29 '18 at 14:52
0

Spotify is interrupting your audio session, so it is no longer active, hence your app is no longer the Now Playing App and no longer receives remote control events.

You need to call

if (![[AVAudioSession sharedInstance] setActive:YES error:&error]) {
    // do something about error
}

again at some point, when your app returns to the foreground or when the interruption ends (by observing the AVAudioSessionInterruptionNotification notification, this is important if you want to recover from phone calls and other interrupting events). More info available in the Responding to Audio Session Interruptions document.

Rhythmic Fistman
  • 34,352
  • 5
  • 87
  • 159