Audio Player play in background and should work based off of hardware mute switch

Your Audio Session Category might be set incorrectly. Since you want to respect the mute switch, you should use SoloAmbient

AVAudioSessionCategorySoloAmbient

The category for default category, used unless you set a category with the setCategory:error: or setCategory:withOptions:error: method.

Your audio is silenced by screen locking and by the Silent switch (called the Ring/Silent switch on iPhone).

By default, using this category implies that your app’s audio is nonmixable—activating your session will interrupt any other audio sessions which are also nonmixable. To allow mixing, use the AVAudioSessionCategoryAmbient category instead.

Available in iOS 3.0 and later.

You appear to have used this category:

AVAudioSessionCategoryPlayback

The category for playing recorded music or other sounds that are central to the successful use of your app.

When using this category, your app audio continues with the Silent switch set to silent or when the screen locks. (The switch is called the Ring/Silent switch on iPhone.) To continue playing audio when your app transitions to the background (for example, when the screen locks), add the audio value to the UIBackgroundModes key in your information property list file.

By default, using this category implies that your app’s audio is nonmixable—activating your session will interrupt any other audio sessions which are also nonmixable. To allow mixing for this category, use the AVAudioSessionCategoryOptionMixWithOthers option.

Available in iOS 3.0 and later.

Source: https://developer.apple.com/library/prerelease/ios/documentation/AVFoundation/Reference/AVAudioSession_ClassReference/index.html#//apple_ref/doc/constant_group/Audio_Session_Categories


Am happy to say, I found how skype is achieving this feature.

In foreground we can use AVAudioSession with any one category to play ringtone.

AVAudioSession *session = [AVAudioSession sharedInstance];
[session setCategory: AVAudioSessionCategorySoloAmbient error:&error];
[session setActive:YES error:nil];

NSURL * audioFileUrl = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"test1" ofType:@"mp3"]];
AVPlayer *player = [[AVPlayer alloc] initWithURL: audioFileUrl];
[player play];

In background we have to use local notification with custom sound. This will work with hardware mute switch. But here sound file length should not exceed 30 seconds.

    UILocalNotification* notification = [[UILocalNotification alloc] init];
    [notification @"Title"];
    [notification setAlertBody:@"Body"];
    [notification setAlertAction:noteAction];
    [notification setSoundName:@"ringtone.mp3"];
    [[UIApplication sharedApplication] presentLocalNotificationNow:notification];

Hope this will be useful :).