How to Show External Window when Mirroring (iOS and Swift UI)

I’m implementing a feature in my iPhone/iPad app where when the iPhone is connected to an external display, the iPhone acts as a controller and the external display shows a non-interactive view. I’m using SwiftUI. Here’s how I’ve implemented it in the SceneDelegate, following Apple’s documentation.

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let windowScene = scene as? UIWindowScene else { return }
        if session.role == .windowApplication {
            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = UIHostingController(rootView: ContentView())
            window.makeKeyAndVisible()
        }
        
        if session.role == .windowExternalDisplayNonInteractive {
            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = UIHostingController(rootView: ExternalView())
            window.makeKeyAndVisible()
        }
    }

Where, of course, ContentView should be displayed on the iPhone and ExternalView is displayed on the external display.

Here’s my info.plist entry if that helps at all.

Ok, so this works fine for most cases, like when screen mirroring from my iPhone to a TV using AirPlay. Both views are displayed correctly. The problem I’m having, though, is that in certain cases, like trying to do a movie recording in QuickTime with the iPhone as the source or adding the iPhone as a video capture device in StreamLabs, the iPhone’s screen (with the ContentView) is mirrored, instead of showing the ExternalView. The ExternalView needs to be displayed when using these apps.

When looking at UIApplication.shared.openSessions, only one session is listed as described bellow

    ▿ 1 member
      - <UISceneSession: 0x283594ac0; role: UIWindowSceneSessionRoleApplication; persistentIdentifier: ED82F2B9-17EC-435F-8E20-439CECCA92F6> {
        scene = <UIWindowScene: 0x117d051e0>;
        configuration = <UISceneConfiguration: 0x283595cc0; name: ContentView; role: UIWindowSceneSessionRoleApplication> {
            sceneClass = 0x0;
            delegateClass = SwiftUI.AppSceneDelegate;
            storyboard = 0x0;
        };
    } #0
        - super: NSObject

Is there a way to “create” a new session for screen mirroring? I’m beginning to worry that this is not possible with apps like QuickTime and StreamLabs and is not something I can fix on my end.

Anyway, if you have any solutions to this issue I would very much appreciate any feedback at all.

This topic was automatically closed after 166 days. New replies are no longer allowed.