2

Edit:

having found a solution for issue 2 (and kind of getting the impression that there is no easy, out of the box solution for issue 1) I decided to close this question and rather create another one some time specifically for the pagination problem.


I have two issues with WKWebViews createPDF(configuration:completionHandler:):

  1. no pagination (I know that this issue has been brought up by others and that there seemingly is no automatic solution to this – I guess paginating would be a manual endeavour…)
  2. the html I load seems to be replacing spaces with new lines

The following code…

import SwiftUI
import WebKit

@main
struct PdfCreatorSOApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

struct ContentView: View {
    var body: some View {
        Button("Create PDF") {
            savePdf()
        }
            .padding()
    }
    
    private func savePdf() {
        if let downloadDir = FileManager.default.urls(for: .downloadsDirectory, in: .userDomainMask).first {
            let savePath = downloadDir.appendingPathComponent("swiftPdf").appendingPathExtension("pdf")
            
            let webViewConfiguration = WKWebViewConfiguration()//do I need to set s.th. here?
            
            let webView = WKWebView(frame: .zero, configuration: webViewConfiguration)
            
            let pdfConfiguration = WKPDFConfiguration()
            pdfConfiguration.rect = CGRect(x: 0, y: 0, width: 595.28, height: 841.89)
            
            webView.loadHTMLString(html, baseURL: nil)
            
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
                webView.createPDF(configuration: pdfConfiguration) { result in
                    switch result {
                    
                    case .success(let data):
                        do {
                            try data.write(to: savePath)
                            print("Successfully created and saved pdf…")
                        } catch let error {
                            print("Could not _save_ pdf: \(error)")
                        }
                    case .failure(let error):
                        print("Could not create pdf: \(error)")
                    }
                }
            }
        }
    }
}

let html = """
<html>
<body>
<h1>Some Title</h1>
<p>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Tellus integer feugiat scelerisque varius. Nunc faucibus a pellentesque sit. Sagittis vitae et leo duis. Posuere lorem ipsum dolor sit amet consectetur. Porta non pulvinar neque laoreet suspendisse interdum. Dui faucibus in ornare quam viverra orci. Nulla facilisi etiam dignissim diam quis enim. Elementum pulvinar etiam non quam lacus suspendisse. Donec enim diam vulputate ut pharetra sit amet aliquam. Nunc mattis enim ut tellus elementum sagittis vitae. Vitae semper quis lectus nulla at volutpat diam ut. Enim eu turpis egestas pretium aenean pharetra magna ac.

    Cras sed felis eget velit aliquet sagittis id consectetur purus. Urna nunc id cursus metus aliquam eleifend mi. Interdum varius sit amet mattis vulputate enim nulla aliquet. At risus viverra adipiscing at in tellus integer feugiat. Dolor purus non enim praesent elementum facilisis leo vel fringilla. Interdum velit euismod in pellentesque massa placerat duis ultricies. Amet facilisis magna etiam tempor orci eu. Proin fermentum leo vel orci porta non pulvinar neque. Et magnis dis parturient montes nascetur ridiculus mus mauris vitae. Sagittis orci a scelerisque purus.
</p>
</body>
</html>
"""

…produces this output: enter image description here

Is there something missing in my WKWebViewConfiguration()?

appfrosch
  • 1,146
  • 13
  • 36

1 Answers1

2

EDITED:

This is just a guess, but I don't think it's replacing spaces with newlines. It's wrapping what it thinks is a narrow web page as narrowly as possible (at each word).

Try adjusting the frame size of webView and see if that helps?

let webView = WKWebView(frame: .zero,... // per comments this didn't help.

Or try adjusting the size of the web page via CSS:

<p> <div **style='width: 600'**> lorem.... </div> // per comments this did
Nicholas Rees
  • 723
  • 2
  • 9
  • Doesn't make a difference I'm afraid, just tried it. – appfrosch Feb 01 '21 at 19:43
  • 1
    Bummer. you could play around with various ways to make the width larger, like changing the HTML

    lorem....
    – Nicholas Rees Feb 01 '21 at 19:48
  • That's definitely the right direction: playing with css styles. When I define a certain width though, now there is no wrapping at all But at least now I know what to look further into! – appfrosch Feb 02 '21 at 08:18
  • I just found the time to take another look into this now. Having done that, I realised that I had specified the width fo `html` in my css–changing that to `body` really does the trick for my issue 2. What I am missing now is pagination, but most likely I will have to open up another question for that to query suggestions. – appfrosch Feb 04 '21 at 17:34
  • https://www.techjunkie.com/how-to-use-page-breaks-in-html/ Do the page breaks in the HTML as well. – Nicholas Rees Feb 04 '21 at 21:05
  • That's a cool idea and while it does work when opening such an html file with Safari and printing it does not work for `WkWebView.createPDF(configuration:completionHandler:)` unfortunately... – appfrosch Feb 05 '21 at 15:11
  • @ASSeeger figure out the page breaks? – cvb Jul 20 '21 at 20:50
  • 1
    I'm struggling with the same issue, as I urgently have to move away from the legacy `WebView`. It's unbelievable Apple still hasn't taken the time to fix the issues and bring `WKWebView` printing to the level they had with old web view. If you did figure out the page breaks, it would be great to know how! – Tritonal Apr 28 '22 at 10:11
  • I have worked around this problem by generating each HTML page as a separate PDF, then stitching all the PDFs back together in the end. It's not ideal, but it works for my situation. – Clifton Labrum May 05 '22 at 06:46
  • I tried to adopt this example code for my MacOS App, but executing always leads to `Could not create pdf: Error Domain=WKErrorDomain Code=1 "Unknown error" UserInfo={NSLocalizedDescription=Unknown Error.}` in the console. What is this unknown error? – mihema Aug 22 '22 at 10:39