A share card must render consistently outside the layout that normally hosts its components. Device size, Dynamic Type, opaque backgrounds, and raster scale can all change the exported result.
Build a fixed export canvas from reusable product visuals:
@MainActor
func renderPNG<Content: View>(
_ content: Content,
size: CGSize
) -> Data? {
let renderer = ImageRenderer(
content: content.frame(width: size.width, height: size.height)
)
renderer.scale = 3
renderer.isOpaque = false
return renderer.uiImage?.pngData()
}
Render at a known logical size and scale to the target pixels. Supersampling and downscaling can improve text and curved edges while preserving final dimensions.
Reuse the same recovery ring, battery, and sleep visuals seen in the app. Separate their data and styling from interactive screen containers so export does not duplicate product logic.
Write the PNG to a temporary file and present the system share sheet with its URL. Clean temporary artifacts later.
Missing metrics need explicit card availability or placeholders. Never export a persuasive-looking zero when the value is unknown.
Snapshot tests can verify dimensions, alpha at rounded corners, light and dark variants, and long localized text. Shareable output is a product surface, so it deserves deterministic rendering rather than a screenshot of whatever happens to be on screen.