<!--
{
  "documentType" : "article",
  "framework" : "AVFAudio",
  "identifier" : "/documentation/AVFAudio/responding-to-audio-route-changes",
  "metadataVersion" : "0.1.0",
  "role" : "article",
  "title" : "Responding to audio route changes"
}
-->

# Responding to audio route changes

Observe audio session notifications to ensure that your app responds appropriately to route changes.

## Discussion

An important responsibility of [`AVAudioSession`](/documentation/AVFAudio/AVAudioSession) is managing audio route changes. A route change occurs when the system adds or removes an audio input or output. Route changes occur for several reasons, including a user plugging in a pair of headphones, connecting a Bluetooth LE headset, or unplugging a USB audio interface. When these changes occur, the audio session reroutes audio signals accordingly and broadcasts a notification containing the details of the change to any registered observers.

An important behavior related to route changes occurs when a user plugs in or removes a pair of headphones (see Playing audio in <doc://com.apple.documentation/design/human-interface-guidelines>). When users connect a pair of wired or wireless headphones, they’re implicitly indicating that audio playback should continue, but privately. They expect an app that’s currently playing media to continue playing without pause. However, when users *disconnect* their headphones, they don’t want to automatically share what they’re listening to with others. Applications should respect this implicit privacy request and automatically pause playback when users disconnect their headphones.

> Note:
> <doc://com.apple.documentation/documentation/AVFoundation/AVPlayer> monitors your app’s audio session and responds appropriately to route changes. When users connect headphones, playback continues as expected. When they disconnect their headphones, playback is automatically paused. To observe this player behavior, key-value observe the player’s <doc://com.apple.documentation/documentation/AVFoundation/AVPlayer/rate> property so that you can update your user interface as the player pauses playback.

### Observe route changes

You can directly observe route change notifications posted by the audio session. This might be useful if you want the system to notify you when a user connects headphones so you can present an icon or message in the player interface.

To respond to audio route changes, observe notifications of type [`routeChangeNotification`](/documentation/AVFAudio/AVAudioSession/routeChangeNotification).

```swift
func observeRouteChanges() async {
    // Observe route change notifications.
    for await notification in NotificationCenter.default.notifications(
        named: AVAudioSession.routeChangeNotification
    ) {
        handleRouteChange(notification: notification)
    }
}

func handleRouteChange(notification: Notification) {
    // To be implemented.
}
```

### Respond to route changes

The posted <doc://com.apple.documentation/documentation/Foundation/Notification> object contains a populated user-information dictionary providing the details of the route change. Determine the reason for this change by retrieving the [`AVAudioSession.RouteChangeReason`](/documentation/AVFAudio/AVAudioSession/RouteChangeReason) value from the dictionary. When a user connects a new device, the reason is [`AVAudioSession.RouteChangeReason.newDeviceAvailable`](/documentation/AVFAudio/AVAudioSession/RouteChangeReason/newDeviceAvailable), and when a user removes a device, the reason is [`AVAudioSession.RouteChangeReason.oldDeviceUnavailable`](/documentation/AVFAudio/AVAudioSession/RouteChangeReason/oldDeviceUnavailable).

When a new device becomes available, you ask the audio session for its [`currentRoute`](/documentation/AVFAudio/AVAudioSession/currentRoute) to determine where the audio output is currently routed. This query returns an [`AVAudioSessionRouteDescription`](/documentation/AVFAudio/AVAudioSessionRouteDescription) object that lists all of the audio session’s inputs and outputs. When the user removes a device, you retrieve the route description for the previous route from the user-information dictionary. In both cases, you query the route description for its outputs, which returns an array of port description objects providing the details of the audio output routes.

```swift
func handleRouteChange(notification: Notification) {
    guard let userInfo = notification.userInfo,
        let reasonValue = userInfo[AVAudioSessionRouteChangeReasonKey] as? UInt,
        let reason = AVAudioSession.RouteChangeReason(rawValue: reasonValue) else {
            return
    }

    // Switch over the route change reason.
    switch reason {

    case .newDeviceAvailable: // New device found.
        let session = AVAudioSession.sharedInstance()
        headphonesConnected = hasHeadphones(in: session.currentRoute)

    case .oldDeviceUnavailable: // Old device removed.
        if let previousRoute =
            userInfo[AVAudioSessionRouteChangePreviousRouteKey] as? AVAudioSessionRouteDescription {
            headphonesConnected = hasHeadphones(in: previousRoute)
        }

    default: ()
    }
}

func hasHeadphones(in routeDescription: AVAudioSessionRouteDescription) -> Bool {
    // Check whether an output has a port type of headphones.
    return routeDescription.outputs.contains(where: { $0.portType == .headphones })
}
```

---

Copyright &copy; 2026 Apple Inc. All rights reserved. | [Terms of Use](https://www.apple.com/legal/internet-services/terms/site.html) | [Privacy Policy](https://www.apple.com/privacy/privacy-policy)