Presenting content on Connected Display not working on iOS 27

I have an app that displays different content on a connected display (following this guide).

It's working fine on iOS 26 but no longer is working in iOS 27 (both dev betas) + the latest SDKs.

I tried to find any update notes but I couldn't find anything so I'm not sure if I'm doing something wrong or if it's an actual bug.

I was able to simplify it down to the simplest case here:

import SwiftUI

// App Delegate to setup the scene delegate
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(_: UIApplication, didFinishLaunchingWithOptions _: [UIApplication.LaunchOptionsKey: Any]? = nil) -> Bool {
        print("Calling didFinishLaunchingWithOptions")
        return true
    }

    func application(_: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options _: UIScene.ConnectionOptions) -> UISceneConfiguration {
        print("Calling configurationForConnecting")
        let sceneConfig = UISceneConfiguration(name: nil, sessionRole: connectingSceneSession.role)
        sceneConfig.delegateClass = WindowSceneDelegate.self
        return sceneConfig
    }
}

// Scene delegate that sets up the view
class WindowSceneDelegate: UIResponder, UIWindowSceneDelegate {
    var window: UIWindow?

    func scene(_ scene: UIScene, willConnectTo _: UISceneSession, options _: UIScene.ConnectionOptions) {
        print("Calling scene(willConnectTo:) with role \(scene.session.role)")
        guard let windowScene = (scene as? UIWindowScene) else { return }
        let window = UIWindow(windowScene: windowScene)

        if scene.session.role == .windowExternalDisplayNonInteractive {
            window.rootViewController = UIHostingController(rootView: ExternalDisplay())
        } else {
            window.rootViewController = UIHostingController(rootView: ContentView())
        }

        self.window = window
        window.makeKeyAndVisible()
    }
}


struct ExternalDisplay: View {
    var body: some View {
        Text("Other World!")
    }
}

struct ContentView: View {
    var body: some View {
        Text("Hello, world!")
    }
}

I also have my Info showing "Enable Multiple Scenes" set to true.

I can screen mirror this app to my Mac (same result with an Apple TV).

On iOS 26, on my iPhone, I'd see "Hello World!" and on the connected display, I'd see "Other World!".

On iOS 27, this is no longer the case. On my connected display, I just see "Hello World".

I'm trying to figure out if I've missed something or if this is a dev beta bug.

Answered by Engineer in 896255022

Hey there!

That is correct. Starting with iOS 27, the system no longer connects a windowExternalDisplayNonInteractive scene to the app. Instead, you can register a scene accessory onto a UIViewController instance like so:

    override func viewDidLoad() {
        super.viewDidLoad()

        // Describe the scene to present, including the delegate that attaches its window.
        let configuration = UISceneConfiguration()
        configuration.delegateClass = ExternalDisplaySceneDelegate.self

        // Register the accessory so the system can present this content on an external display.
        let accessory = UISceneAccessory.externalNonInteractive(sceneConfiguration: configuration)
        displayRegistration = registerSceneAccessory(accessory)
    }

Some additional things to note:

  • The UISceneAccessoryRegistration that you get back from registerSceneAccessory has some useful properties like isEnabled to toggle the accessory, and isAvailable to check if an accessory of this kind is available.
  • The system will pick the most relevant registration based on view controller depth and presentation state.

— Miguel

I found this relevant tidbit in the release notes that's possibly it?

In apps built with the iOS 27.0 SDK, windowExternalDisplayNonInteractive scenes are no longer offered automatically by the system. Use UIViewController.registerSceneAccessory(_:) with a UISceneAccessory.externalNonInteractive instance to display non-interactive content on external display scenes. (177015874)

Are there any examples for how to use this?

Accepted Answer

Hey there!

That is correct. Starting with iOS 27, the system no longer connects a windowExternalDisplayNonInteractive scene to the app. Instead, you can register a scene accessory onto a UIViewController instance like so:

    override func viewDidLoad() {
        super.viewDidLoad()

        // Describe the scene to present, including the delegate that attaches its window.
        let configuration = UISceneConfiguration()
        configuration.delegateClass = ExternalDisplaySceneDelegate.self

        // Register the accessory so the system can present this content on an external display.
        let accessory = UISceneAccessory.externalNonInteractive(sceneConfiguration: configuration)
        displayRegistration = registerSceneAccessory(accessory)
    }

Some additional things to note:

  • The UISceneAccessoryRegistration that you get back from registerSceneAccessory has some useful properties like isEnabled to toggle the accessory, and isAvailable to check if an accessory of this kind is available.
  • The system will pick the most relevant registration based on view controller depth and presentation state.

— Miguel

Presenting content on Connected Display not working on iOS 27
 
 
Q