SwiftUI views to images
SwiftUI is an amazing tool to create all sorts of views in our applications. But many times we want that ease of use to generate graphics that can be used outside of apps, usually as simple image files. That's why is so useful to know how to generate images from SwiftUI views. This power unlocks a new world of possibilities!
Sadly, SwiftUI doesn't provide a native way of generating images from its views. We need to resort to tricks used in its ancestor frameworks.
The main use case that I have for this is to generate images from a command line tool, that means we need to use AppKit since the code will run in a macOS machine. You can do a very similar thing in iOS with UIKit, for example, if you want to share something via share sheets.
Rasterize SwiftUI views
SwiftUI provides a very good interoperability with AppKit. You can display SwiftUI views in AppKit views and vice versa. We can use that capability to use AppKit APIs.
First, we need to create a
NSHostingView with the SwiftUI view that you want to create the image from.
let nsView = NSHostingView(rootView: swiftUIView)
NSView in hand, the rest of the process is no different that what you would do to rasterize a native AppKit view.
let bitmapRep = nsView.bitmapImageRepForCachingDisplay(in: nsView.bounds)!
bitmapRep.size = nsView.bounds.size
nsView.cacheDisplay(in: nsView.bounds, to: bitmapRep)
This code gives you a bitmap representation of the view. This is already an image, but one that can hardly be used. If you want to use the image in any other software is very likely that you want to convert it to a common format and save it to disk.
let data = image.representation(using: .jpeg, properties: [:])
try data?.write(to: path)
And that's it. Now you have a jpeg image of your SwiftUI view stored on disk. With it, you can do whatever you please! So much power!
I've packaged up this code in a Swift Package. You can find it on GitHub and even in the Swift Package Index. If you have any suggestions or improvements, feel free to open a PR. It's not like I'm an expert on AppKit!
If you want to know how to share a package in the Swift Package Index make sure you watch this video.
If you liked this article please consider supporting me