Sapan Diwakar

Software developer

Follow me on Twitter Check out my code on GitHub View some of my designs on Dribbble Take a look at my Linked In profile

Switch to a new song/audio in background for iOS

If you have a music app, you might be using a code like this to play songs in your iOS app:

- (void)next
{
  // Find new index
  NSUInteger newIndex;

  // Create a new audio player for this index
  NSError *error = nil;
  AVAudioPlayer *newAudioPlayer =[[AVAudioPlayer alloc] initWithContentsOfURL:[(MDAudioFile *)[soundFiles objectAtIndex:selectedIndex] filePath] error:&error];

  if (error)
    NSLog(@"%@", error);

  // Stop the old player
  [player stop];
  self.player = newAudioPlayer;
  [newAudioPlayer release];

  // Play the new player
  player.delegate = self;
  player.volume = volumeSlider.value;
  [player prepareToPlay];
  [player setNumberOfLoops:0];
  [player play];
}

It works great when the app is in the foreground. But, starting from iOS8, it doesn't work when your app is playing music in the background even if the background mode is correctly configured.

When the UIBackgroundModes key contains the audio value, the system’s media frameworks automatically prevent the corresponding app from being suspended when it moves to the background. As long as it is playing audio or video content or recording audio content, the app continues to run in the background. However, if recording or playback stops, the system suspends the app.

This means that your app with continue operating in the background only as long as the audio is playing. Notice that we stopped the audio player before starting the new song. This causes the app to be suspended before it can start a new song.

In order for AVAudioPlayer to start playing while the application is in background, your app must support remote control events. These are the audio controller interface prex/nex/play/pause on the left of the multitask switcher taskbar. The solution is to add this line in the viewDidLoad of the first view controller in your app.

// Register for playing audio controller when in background to allow changing songs while in background
// See http://sapandiwakar.in/switch-to-a-new-song-in-background-for-ios/
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];

That's all. Your song switching is all good again. Enjoy!