I'm building a visionOS app where users can place canvases into the 3D environment. These canvases are RealityKit
entities that render web content using a WKWebView
. The web view is regularly snapshotted, and its image is applied as a texture on the canvas surface.
When the user taps on a canvas, a WindowGroup
is opened that displays the same shared WKWebView instance. This works great: both the canvas in 3D and the WindowGroup
reflect the same live web content.
The canvas owns the WKWebView
and keeps a strong reference to it.
Problem:
Once the user closes the WindowGroup, the 3D canvas stops receiving snapshot updates. The snapshot loop task is still running (verified via logs), but WKWebView.takeSnapshot(...)
never returns — the continuation hangs forever. No error is thrown, no image is returned.
If the user taps the canvas again (reopening the window), snapshots resume and everything works again.
@MainActor
private func getSnapshot() async -> UIImage? {
guard !webView.isLoading else { return nil }
let config = WKSnapshotConfiguration()
config.rect = webView.bounds
config.afterScreenUpdates = true
return await withCheckedContinuation { continuation in
webView.takeSnapshot(with: config) { image, _ in
continuation.resume(returning: image)
}
}
}
What I’ve already verified:
- The
WKWebView
is still in memory. - The snapshot loop (Task) is still running; it just gets stuck inside takeSnapshot(...).
- I tried keeping the WKWebView inside a hidden UIWindow (with .alpha = 0.01, .windowLevel = .alert + 1, and isHidden = false).
Suspicion It seems that once a WKWebView is passed into SwiftUI and rendered (e.g., via UIViewRepresentable), SwiftUI takes full control over its lifecycle. SwiftUI tells WebKit "This view got closed" and WebKit reacts by stopping the WKWebView. Even though it still exists in memory and is being hold by a strong reference to it in the Canvas-Entity.<br> Right now, this feels like a one-way path:
- Starting from the canvas, tapping it to open the WindowGroup works fine.
- But once the WindowGroup is closed, the WebView freezes, and snapshots stop until the view is reopened.
Questions Is there any way under visionOS to:
- Keep a WKWebView rendering after its SwiftUI view (WindowGroup) is dismissed?
- Prevent WebKit from suspending or freezing the view?
- Embed the view in a persistent system-rendered context to keep snapshotting functional?
For context, here's the relevant SwiftUI setup<br>
struct MyWebView: View {
var body: some View {
if let webView = WebViewManager.shared.getWebView() {
WebViewContainer(webView: webView)
}
}
}
struct WebViewContainer: UIViewRepresentable {
let webView: WKWebView
func makeUIView(context: Context) -> UIView {
return webView
}
func updateUIView(_ uiView: UIView, context: Context) {}
}