Creating PDFs on MacOS without UIKit

Greetings,

this may be an odd question but I was not able to find an answer to this.

So I am developing this pure MacOS program for a client and one thing he wants is to create some PDFs along the way. Great chance I thought to try out this fancy Swift 5 with SwiftUI and so far it's going great, most of the program is up and running but I've hit a wall with the PDF generation, which I thought would be one of the easiest parts.

Since it's a pure MacOS program, UIKit is not available but there is not a single tutorial out there for generating PDFs which is not using UIKit to do it. It seems people only want to create PDFs on iOS.

Can someone give me a small breakdown or starter or tutorial or skeleton on how I would do that? Thanks and have a nice day

Replies

  • Thanks, I found this but no, that looked old and outdated, plus I wanted to automatically save them to disk, not display a print dialogue. I was looking for a simple, pure MacOS PDFKit implementation

Add a Comment

Maybe purchase a commercial license for Ghostscript, or for Sanface txt2pdf, or some other existing tool that provides this?

Here is a case for MacOS.

https://stackoverflow.com/questions/44640022/draw-on-a-pdf-using-swift-on-macos

Hope that will help.

On iOS, structure is like this:

func createPdfAndSave() -> Bool  {
    // 1. Create Print Formatter with input text.
    let formatter = UIMarkupTextPrintFormatter(markupText: "") // Some text textView.text)
    
    // 2. Add formatter with pageRender
    let render = MultiPagesUIPrintPageRenderer(howManyPages: kDrawOn2Columns ? 1 : 2) // UIPrintPageRenderer()
    render.addPrintFormatter(formatter, startingAtPageAt: 0)
    
    // 3. Assign paperRect and printableRect
    let page = CGRect(x: 0, y: 0, width: kPageWidth, height: kPageHeight) // A4, 72 dpi
    let printable = page.insetBy(dx: 0, dy: 0)
    
    render.setValue(NSValue(cgRect: page), forKey: "paperRect")
    render.setValue(NSValue(cgRect: printable), forKey: "printableRect")
    
    // 4. Initialize drawing areas
    
    // 5. Create PDF context and draw
    let rect = CGRect.zero
    
    let pdfData = NSMutableData()
    UIGraphicsBeginPDFContextToData(pdfData, rect, nil)
    render.prepare(forDrawingPages: NSMakeRange(0, render.numberOfPages))
    let bounds = UIGraphicsGetPDFContextBounds()
    
    for iPage in 1...render.numberOfPages {
        UIGraphicsBeginPDFPage();
        render.drawPage(at: iPage - 1, in: bounds)
    }  
    UIGraphicsEndPDFContext();
    
    // 6. Save PDF file
    
    do {
        let documentDirUrl = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
        let fileNameWithPDFExtension = filenameShort + ".pdf"
        let indexFileUrl = documentDirUrl.appendingPathComponent(fileNameWithPDFExtension)
        return pdfData.write(to: indexFileUrl, atomically: true)    // true if written
    } catch {
        print(error)
        return false
    }

}

Thanks for the suggestions, the only sort of native way I was able to find was to create a WKWebView, feed it HTML and use the .createPDF() function to get to my PDF. Odd to me that the native functionality is available on iOS but not on MacOS