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.
My application is actually quite a similar concept to the one in Apple's documentation. The iPhone/iPad will always be used as a controller while the external display will always show the content, in Apple's case, a game. For this reason, when mirroring the game to QuickTime or StreamLabs, the actual game needs to be mirrored, not the controller. Here's the example I'm talking about in Apple's documentation so that you can visualize it.
Current Implementation
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 or QuickTime. And here's my info.plist entry if that's relevant to you.
Outcome and the Problem
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 shown 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 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.