Audio playing while app in background iOS

Darren picture Darren · Apr 25, 2014 · Viewed 15.4k times · Source

I have an app mostly based around Core Bluetooth. When something specific happens, the app is woken up using Core Bluetooth background modes and it fires off an alarm, however I can't get the alarm working when the app is not in the foreground.

I have an Alarm Singleton class which initialises AVAudioPlayer like this:

NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle]
                    pathForResource:soundName
                             ofType:@"caf"]];

self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive: YES error: nil];
[self.player prepareToPlay];
self.player.numberOfLoops = -1;
[self.player setVolume:1.0];

NSLog(@"%@", self.player);

This is the method that is called when my alarm code is called:

-(void)startAlert
{
    NSLog(@"%s", __FUNCTION__);

    playing = YES;
    [self.player play];
    NSLog(@"%i", self.player.playing);

    if (vibrate) {
        [self vibratePattern];
    }
}

Now when the app is in the foreground, self.player.playing returns 1 however when the app is in the background self.player.playing returns 0. Why would this be? All the code is being called, so the app is awake and functioning. The vibrate works perfectly which uses AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);

Any idea why this sound won't play?

Thanks

Answer

Michael Dorner picture Michael Dorner · Apr 28, 2014

Apple has a nice Technical Q&A article about this in its documentation (see also Playing and Recording Background Audio).

I think one big thing missing is that you haven't activated the Audio Background Mode in the Xcode settings: enter image description here

Maybe also adding [self.player prepareToPlay] in your alert method is helpful.