CompositorLayer C/Objective-C API

The Drawing fully immersive content using Metal guide describes how to use Metal for visionOS immersive experiences, but seemingly requires swift to bring up the required CompositorLayer.

@main
struct MyApp: App {
    var body: some Scene {
        ImmersiveSpace(id: "MyContent") {
            CompositorLayer { layerRenderer in
                let renderThread = Thread {
                    let engine = myEngineCreate(layerRenderer)
                    myEngineRenderLoop(engine)
                }
                renderThread.name = "Render Thread"
                renderThread.start()
            }
        }
}

The ImmersiveSpace scene can presumably be replaced with a call to

[UIApplication.sharedApplication activateSceneSessionForRequest:[UISceneSessionActivationRequest requestWithRole:UISceneSessionRoleImmersiveSpaceApplication] errorHandler:nil]

But is there a replacement for CompositorLayer? Or some other way to produce a cp_layer_renderer?

Perhaps it would be possible to write a small swift helper for this, but given the swift interface for CompositorLayer how would that be tied to an existing UIScene as created above?

@available(visionOS 1.0, *)
public struct CompositorLayer : SwiftUI.ImmersiveSpaceContent {
  public init(configuration: any _CompositorServices_SwiftUI.CompositorLayerConfiguration = .default, renderer: @escaping (CompositorServices.LayerRenderer) -> Swift.Void)
  public var body: Swift.Never {
    get
  }
  public typealias Body = Swift.Never
}

Replies

I tried

[UIApplication.sharedApplication activateSceneSessionForRequest:[UISceneSessionActivationRequest requestWithRole:UISceneSessionRoleImmersiveSpaceApplication] errorHandler:nil]

But doing so results in

Error Domain=UISceneErrorDomain Code=1 "Scene session activation failed because the requested role "UISceneSessionRoleImmersiveSpaceApplication" is not supported.”

Not sure why?

However, using a manifest of

  <key>UIApplicationSceneManifest</key>
	<dict>
		<key>UIApplicationPreferredDefaultSceneSessionRole</key>
		<string>UISceneSessionRoleImmersiveSpaceApplication</string>
		<key>UIApplicationSupportsMultipleScenes</key>
		<true/>
		<key>UISceneConfigurations</key>
		<dict>
			<key>UISceneSessionRoleImmersiveSpaceApplication</key>
			<array>
				<dict>
					<key>UISceneConfigurationName</key>
					<string>ImmersiveApp</string>
				</dict>
			</array>
		</dict>
	</dict>

Seems to work, giving callbacks to application:configurationForConnectingSceneSession:options with

<UISceneSession: 0x60000179c540; role: UISceneSessionRoleImmersiveSpaceApplication; persistentIdentifier: org.qt-project.example-xrsimulator.rasterwindow:SFBSystemService-7F604A14-E3DE-43D2-86E0-05CC29DAE1DC; scene: (nil); configuration: <UISceneConfiguration: 0x60000179d140>; userInfo: <__NSDictionary0: 0x1e494e2e0>>

So I’m not sure why the explicit activateSceneSessionForRequest API doesn’t work?