It seems that the accepted way of doing this is to set the AV category to AVAudioSessionCategoryPlayAndRecord, and then set the property kAudioSessionOverrideAudioRoute_Speaker. I'm using the category AVAudioSessionCategoryPlayback, because it gives me the proper volume with the headphones not plugged in. When I set the category to AVAudioSessionCategoryPlayAndRecord, the audio playback through the speaker with the headphones not plugged in is very soft. I wasn't able to get the desired behavior of playback through the speaker with headphones plugged in with EITHER AV category.
Here's my code with the category set to AVAudioSessionCategoryPlayback:
AVAudioSession* session = [AVAudioSession sharedInstance];
NSError* error = nil;
BOOL success = [session setActive: YES error: &error];
if (success)
success = [session setCategory: AVAudioSessionCategoryPlayback error: &error];
// To allow ipod music to play
UInt32 doSetProperty = 1;
AudioSessionSetProperty (kAudioSessionProperty_OverrideCategoryMixWithOthers, sizeof (doSetProperty), &doSetProperty);
AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, hardwareRoutePropertyListener, nil);
UInt32 audioRouteOverride = kAudioSessionOverrideAudioRoute_Speaker;
AudioSessionSetProperty(kAudioSessionProperty_OverrideAudioRoute,
sizeof (audioRouteOverride),
&audioRouteOverride
);