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;
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…