I want to create a pdf on macOS with the new WKWebView.pdf(configuration:)
which was introduced in macOS 12/iOS 15. It tries to make use of the new async/await functionality (which I most likely have not grasped entirely I am afraid...).
Right now, I am getting an error that I have no idea how to handle:
Error Domain=WKErrorDomain Code=1 "An unknown error occurred"
UserInfo={NSLocalizedDescription=An unknown error occurred}
I try to load a html string into a web view, which I then want to generate the pdf from. The function I use to generate my PDFDocument
looks like this:
func generatePdf() async {
let webView = WKWebView()
await webView.loadHTMLString(html, baseURL: nil)
let config = WKPDFConfiguration()
config.rect = .init(origin: .zero, size: .init(width: 595.28, height: 841.89))
do {
//this is where the error is happening
let pdfData = try await webView.pdf(configuration: config)
self.pdf = PDFDocument(data: pdfData)
} catch {
print(error) //this error gets printed
}
}
My best guess as it currently stands is that WKWebView
's loadHTMLString
has not finished loading the html–I did allow for outgoing connection in the app sandbox that's not it...
For the sake of completeness, here's the entire code:
import SwiftUI
import PDFKit
import WebKit
@main
struct AFPdfApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
struct ContentView: View {
@StateObject private var vm = ViewModel()
var body: some View {
VStack {
TextEditor(text: $vm.html)
.frame(width: 300.0, height: 200.0)
.border(Color.accentColor, width: 1.0)
.padding()
PdfViewWrapper(pdfDocument: $vm.pdf)
}
.toolbar {
Button("Create PDF") {
Task {
await vm.generatePdf()
}
}
}
}
static let initHtml = """
<h1>Some fancy html</h1>
<h2>…and now how do I create a pdf from this?</h2>
"""
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
class ViewModel: ObservableObject {
@Published var html = """
<h1>Some fancy html</h1>
<h2>…and now let's create some pdf…</h2>
"""
@Published var pdf: PDFDocument? = nil
func generatePdf() async {
let webView = WKWebView()
await webView.loadHTMLString(html, baseURL: nil)
let config = WKPDFConfiguration()
config.rect = .init(origin: .zero, size: .init(width: 595.28, height: 841.89))
do {
let pdfData = try await webView.pdf(configuration: config)
self.pdf = PDFDocument(data: pdfData)
} catch {
print(error)
}
}
}
struct PdfViewWrapper: NSViewRepresentable {
@Binding var pdfDocument: PDFDocument?
func makeNSView(context: Context) -> PDFView {
return PDFView()
}
func updateNSView(_ nsView: PDFView, context: Context) {
nsView.document = pdfDocument
}
}