From 67c2dbcd142dcc6001d8e12c61fc52e5ab185dcd Mon Sep 17 00:00:00 2001 From: Philip Niedertscheider Date: Tue, 21 Apr 2026 18:44:39 +0200 Subject: [PATCH] fix(ui): Skip EDR Metal path on iOS Simulator MTLCreateSystemDefaultDevice() returns a valid device on Apple Silicon iOS Simulator hosts, so EDRMetalView.isSupported returned true and LinkDetailRenderView rendered the QR code through an MTKView. In the simulator, Metal-backed views don't capture reliably via XCUIScreenshot and the wrapping VStack stops exposing as an accessibility image, which broke ScreenshotUITests.testScreenshots at the "link-detail.qr-code.container" lookup. Always return false on simulator so the SwiftUI Image(uiImage:) fallback is used. This has been silently broken on main since #116 landed because the build-test.yml Screenshots job (generate_screenshots_ci / capture_screenshots on a single device) doesn't fail the lane on test failure. --- .../Sources/UI/Components/EDRMetalView.swift | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/Targets/App/Sources/UI/Components/EDRMetalView.swift b/Targets/App/Sources/UI/Components/EDRMetalView.swift index b197030..cda31e8 100644 --- a/Targets/App/Sources/UI/Components/EDRMetalView.swift +++ b/Targets/App/Sources/UI/Components/EDRMetalView.swift @@ -7,10 +7,19 @@ struct EDRMetalView: UIViewRepresentable { /// Whether the current device supports EDR rendering via Metal. /// /// Callers should check this before entering the EDR rendering path to avoid - /// displaying a blank view on unsupported devices (e.g. the iOS Simulator). - /// This property reads from `Renderer.device`, the same shared `MTLDevice` - /// that the renderer uses, so the check is consistent with actual rendering capability. - static var isSupported: Bool { Renderer.device != nil } + /// displaying a blank view on unsupported devices. Always returns `false` on + /// the iOS Simulator: on Apple Silicon hosts `MTLCreateSystemDefaultDevice()` + /// returns a device, but Metal-backed views don't render correctly for + /// `XCUIScreenshot` capture, and the resulting `MTKView` doesn't expose as an + /// accessibility image element. Both matter for the App Store screenshot + /// pipeline, which renders on simulators. + static var isSupported: Bool { + #if targetEnvironment(simulator) + return false + #else + return Renderer.device != nil + #endif + } let imageProvider: (_ contentScaleFactor: CGFloat, _ headroom: CGFloat) -> CIImage?