<!--
{
  "documentType" : "article",
  "framework" : "CoreTelephony",
  "identifier" : "/documentation/CoreTelephony/iphone-quick-switch",
  "metadataVersion" : "0.1.0",
  "role" : "collectionGroup",
  "title" : "iPhone quick switch"
}
-->

# iPhone quick switch

Enable seamless app transition between multiple iPhones.

## Discussion

iPhone quick switch enables your app to receive notifications from the system when someone activates a iPhone as their currently active device for a specific phone number or queries the system about a device’s current state.

> Important: Quick switch signals to your app that it needs to transition active services, such as login credentials and persistent state from a formerly active iPhone to a newly active iPhone. To ensure a high quality user experience, your app, as well as its supporting services need to handle this transition seamlessly, and keep track of both active and passive devices to ensure people aren’t locked out of services your app provides.

There are two ways adopt iPhone quick switching:

- Create a [`CTQuickSwitchManager`](/documentation/CoreTelephony/CTQuickSwitchManager) object, and, optionally, subscribe to the [`CTQuickSwitchManager.Delegate`](/documentation/CoreTelephony/CTQuickSwitchManager/Delegate-swift.protocol) protocol to receive notification state changes.
- Query the a device’s `CTQuickSwitch` state directly.

The following example shows how to create a `CTQuickSwitchManager`, register and de-register for events, check the quick switch state for a specific phone number, and check the device’s current state.

```swift
    
// Create an instance of the `CTQuickSwitchManager` and set the `delegate`.
let manager = CTQuickSwitchManager()
manager.delegate = self // assuming self conforms to CTQuickSwitchManager.Delegate

// Check the QuickSwitch state of a specific phone number.
manager.phoneNumberState(for: "5550") { state, error in
    if let error {
        // handle the error.
        return
    }
    switch state {
        case .active:
        // This device is active.
        case .passive:
        // This device is passive.
        case .notEnrolled:
        // Quick switching isn't configured for this number.
        case .failed:
        fallthrough
        @unknown default:
        break
    }
}

// Check the overall device QuickSwitch state.
manager.getDeviceState { state, error in
    if let error {
        // handle the error.
        return
    }
    if state == .passive {
        // Device is passive.
    }
}

// Register for background launch on QuickSwitch state changes.
CTQuickSwitchManager.registerForLaunchOnQuickSwitchStateEvents { error in
    if let error {
        // Handle the error — app may not be eligible.
        return
    }
    // Successfully registered; the system will wake app in the background on state changes.
}

// Unregister from background launch on QuickSwitch state changes.
CTQuickSwitchManager.unregisterForLaunchOnQuickSwitchStateEvents { error in
    if let error {
        // handle the error.
        return
    }
    // Successfully unregistered
}
```

The following examples show how to create a `CTQuickSwitchManager`, register and de-register for events, check the quick switch state for a specific phone number, and check the device’s current state using asynchronous calls in Swift.

```swift
    // Create an instance of the `CTQuickSwitchManager` and set the delegate.
    let manager = CTQuickSwitchManager()
    manager.delegate = self // Assuming `self` conforms to `CTQuickSwitchManager.Delegate`

    // Check the QuickSwitch state of a specific phone number.
    let state = try await manager.phoneNumberState(for: "5550")
    switch state {
        case .active:
        // This device is active.
        case .passive:
        // This device is passive.
        case .notEnrolled:
        // QuickSwitch is not configured for this number.
        case .failed:
        fallthrough
        @unknown default:
        break
    }
    
    // Check the overall device QuickSwitch state.
    let deviceState = try await manager.deviceState
    if deviceState == .passive {
        // Device is passive.
    }

    // Register for quick switch state events.
    if let _ = try? await CTQuickSwitchManager.registerForLaunchOnQuickSwitchStateEvents()  {
        print("Registration successful.")
    } else {
        print("Registration failed.")
    }

    
    // Un-register for quick switch state events.
    if let _ = try? await CTQuickSwitchManager.unregisterForLaunchOnQuickSwitchStateEvents() {
        print("De-registration successful.")
    } else {
        print("App wasn't registered for launch on quick switch events.")
    }
    
    // Implement the delegate callback to receive state changes.
    func quickSwitchManager(_ manager: CTQuickSwitchManager, didChangeToState state: CTQuickSwitchManager.State) {
        // Handle the updated state.
    }        
    
```

## Topics

### Adopting iPhone quick switch

[`CTQuickSwitchManager`](/documentation/CoreTelephony/CTQuickSwitchManager)

An object that enables an app to register and query a device’s quick switch state.

[`delegate`](/documentation/CoreTelephony/CTQuickSwitchManager/delegate-swift.property)

An object the system notifies to respond to quick switch events.

[`Delegate`](/documentation/CoreTelephony/CTQuickSwitchManager/Delegate-swift.protocol)

Methods you implement to respond to changes in a device’s quick switch state.

### Registering and unregistering for quick switch events

[`+  registerForLaunchOnQuickSwitchStateEvents:`](/documentation/CoreTelephony/CTQuickSwitchManager/registerForLaunch(onQuickSwitchStateEvents:))

Registers the calling app for background launch whenever the device’s quick switch state changes.

[`+  unregisterForLaunchOnQuickSwitchStateEvents:`](/documentation/CoreTelephony/CTQuickSwitchManager/unregisterForLaunch(onQuickSwitchStateEvents:))

Removes the calling app’s registration for background launch on quick switch state changes.

### Responding to quick switch state changes

[`-  quickSwitchManager:didChangeToState:`](/documentation/CoreTelephony/CTQuickSwitchManager/Delegate-swift.protocol/quickSwitchManager(_:didChangeTo:))

Indicates there’s been a change in device’s quick switch state.

### Checking the state of a device

[`-  getDeviceState:`](/documentation/CoreTelephony/CTQuickSwitchManager/getDeviceState(_:))

Gets the quick switch state of the current device.

[`-  getPhoneNumberStateForSuffix:completion:`](/documentation/CoreTelephony/CTQuickSwitchManager/getPhoneNumberState(forSuffix:completion:))

Queries the quick switch state for a phone number whose suffix matches the provided phone number suffix.

[`CTQuickSwitchState`](/documentation/CoreTelephony/CTQuickSwitchState)

Values that describe a device’s quick switch status.



---

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)