Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entering background on iOS4 to play audio

The documentation is rather poorly written when talking about playing audio in the background. It gives the impression that all you have to do to continue playing the audio that you are currently playing is to just add a key/value pair to the info.plist file and wallah, it's magic.

However, this is not the case. For instance, if I play an mp3 that is 2 minutes long, obviously the audio is long enough to be able to play after I hit the home button to send my app to the background. The thing is, even though I have that key/value pair in my info.plist file, it pauses the audio and then resumes playing once I switch back to the app.

Apple states that all frameworks for audio support background and the sound should continue playing up until the point that it ends and then Apple will suspend your app.

So, my question is: What are they doing that I am missing? Do I also have to use their new delegates somehow or call the audio on the applicationDidEnterBackground? To me, that wouldn't make sense since I am not saving state (they do for me with fast app switching) or really handling anything in the background other than audio which they say is supposed to be handled automagically.

like image 802
iwasrobbed Avatar asked Jul 01 '10 21:07

iwasrobbed


People also ask

Can Apple music play in the background?

Under the Capabilities tab, set the Background Modes switch to ON and select the “Audio, AirPlay, and Picture in Picture” option under the list of available modes. With this mode enabled and your audio session configured, your app is ready to play background audio.

How do I add Background Sounds to iOS 15?

Apple added new Background Sounds (rain, bright noise, ocean, and more) to the iPhone with iOS 15. To activate, head to Settings > Accessibility > Audio/Visual > Background Sounds > Toggle to on.


1 Answers

You also need to make calls to beginBackgroundTaskWithExpirationHandler: before you start a song (do it all the time whether in foreground or not) and endBackgroundTask when it ends.

This tells iOS that you want to be able to continue processing even if your app gets put in the background. It does not create a new task or thread, it's just a flag to iOS that you want to keep running. The audio will play to completion without this, but when it completes if you want to start another track you must be able to run in the background.

You can use it like this:

// ivar, initialized to UIBackgroundTaskInvalid in awakeFromNib
UIBackgroundTaskIdentifier bgTaskId; 

When starting an audio player we save the bg task id:

if ([audioPlayer play]) {
  bgTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL];
}

Now the audioPlayerDidFinishPlaying: callback will still occur because we have told iOS that we are doing a task that needs to continue even if we get put in the background. That way we get the callback and can start the next audio file.

- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)success
{
    UIBackgroundTaskIdentifier newTaskId = UIBackgroundTaskInvalid;

    if (self.haveMoreAudioToPlay) {
        newTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:NULL];
        [self playNextAudioFile];
    }

    if (bgTaskId != UIBackgroundTaskInvalid) {
        [[UIApplication sharedApplication] endBackgroundTask: bgTaskId];
    }

    bgTaskId = newTaskId;
}      
like image 171
progrmr Avatar answered Oct 05 '22 08:10

progrmr