Are headphones plugged in? iOS7
This should work, but I cannot test it right now, I'll do in the evening.
- (BOOL)isHeadsetPluggedIn { AVAudioSessionRouteDescription* route = [[AVAudioSession sharedInstance] currentRoute]; for (AVAudioSessionPortDescription* desc in [route outputs]) { if ([[desc portType] isEqualToString:AVAudioSessionPortHeadphones]) return YES; } return NO;}
Just to extend @Antonio's answer. If you need to detect whether the user has pulled out or plugged in the headphone.
#import <AVFoundation/AVFoundation.h>
// [AVAudioSession sharedInstance]; // @Boris edited: you may need it if there is no `AVAudioSession instance` created before. If doesn't work, uncomment this line.[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(audioRouteChangeListenerCallback:) name:AVAudioSessionRouteChangeNotification object:nil];// don't forget to `removeObserver:`
// If the user pulls out he headphone jack, stop playing.- (void)audioRouteChangeListenerCallback:(NSNotification*)notification{ NSDictionary *interuptionDict = notification.userInfo; NSInteger routeChangeReason = [[interuptionDict valueForKey:AVAudioSessionRouteChangeReasonKey] integerValue]; switch (routeChangeReason) { case AVAudioSessionRouteChangeReasonNewDeviceAvailable: NSLog(@"AVAudioSessionRouteChangeReasonNewDeviceAvailable"); NSLog(@"Headphone/Line plugged in"); break; case AVAudioSessionRouteChangeReasonOldDeviceUnavailable: NSLog(@"AVAudioSessionRouteChangeReasonOldDeviceUnavailable"); NSLog(@"Headphone/Line was pulled. Stopping player...."); break; case AVAudioSessionRouteChangeReasonCategoryChange: // called at start - also when other audio wants to play NSLog(@"AVAudioSessionRouteChangeReasonCategoryChange"); break; }}
Swift 3:
To check if headphones are connected
extension AVAudioSession { static var isHeadphonesConnected: Bool { return sharedInstance().isHeadphonesConnected } var isHeadphonesConnected: Bool { return !currentRoute.outputs.filter { $0.isHeadphones }.isEmpty }}extension AVAudioSessionPortDescription { var isHeadphones: Bool { return portType == AVAudioSessionPortHeadphones }}
Then you can just print("isHeadphones connected: \(AVAudioSession.isHeadphonesConnected)")
Listening to Changes
In Swift 3 the syntax is this:
func handleRouteChange(_ notification: Notification) { guard let userInfo = notification.userInfo, let reasonRaw = userInfo[AVAudioSessionRouteChangeReasonKey] as? NSNumber, let reason = AVAudioSessionRouteChangeReason(rawValue: reasonRaw.uintValue) else { fatalError("Strange... could not get routeChange") } switch reason { case .oldDeviceUnavailable: print("oldDeviceUnavailable") case .newDeviceAvailable: print("newDeviceAvailable") if AVAudioSession.isHeadphonesConnected { print("Just connected headphones") } case .routeConfigurationChange: print("routeConfigurationChange") case .categoryChange: print("categoryChange") default: print("not handling reason") }}func listenForNotifications() { NotificationCenter.default.addObserver(self, selector: #selector(handleRouteChange(_:)), name: NSNotification.Name.AVAudioSessionRouteChange, object: nil)}
Notice use of:
if AVAudioSession.isHeadphonesConnected { print("Just connected headphones") }