Writing a simple 'hello world' PDF page in swift for macos and it's coming out blank

51 Views Asked by At

So it seems like almost all the examples out there for writing PDF content in a swift app are for ios. But I need this to run under macos. So for example, I can't use any of the UI functions like UIGraphicsRenderer, etc. I have tried to piece together a test application whose only function is to print 'hello world', but I must be doing something wrong. The PDF does get created and saved, but it has no content. Any advice would be welcome. Here's the print function:

import Foundation
import PDFKit

func printPDF() {
    
    let localURL = FileManager.default.currentDirectoryPath
    let url = URL(fileURLWithPath: localURL).appendingPathComponent("tv-schedule-for-today.pdf")
 
    var pdfDoc: PDFDocument? = PDFDocument()
    
    let page: PDFPage? = PDFPage()
    var mediaBox: CGRect = page!.bounds(for: .mediaBox)
    
    guard let currentContext = CGContext(url as CFURL, mediaBox: &mediaBox, nil) else {
        return
    }
    var context: CGContext? = currentContext

    context!.beginPDFPage(nil)

    let attributes = [
          NSAttributedString.Key.font: NSFont.boldSystemFont(ofSize: 72)
        ]
    let text = "Hello World!"
    text.draw(at: CGPoint(x: 200, y: 300), withAttributes: attributes)

    context!.endPDFPage()

    pdfDoc!.insert(page!, at: 0)
        
    context!.closePDF()

    pdfDoc!.write(to: url as URL)
    
    context = nil

}

Update:

There's an answer here that resolves my problem. Kudos to @Willeke for pointing it out to me.

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

Turns out I had seen it earlier but made an error implementing it. Going over it again I realized I hadn't connected the CGContext with the NSGraphicsContext. Also starting the actual render with page.draw. My corrected code is below, and it works very well now. Thanks everyone! :)

import Foundation
import PDFKit

func printPDF() {
    
    let localURL = FileManager.default.currentDirectoryPath
    let url = URL(fileURLWithPath: localURL).appendingPathComponent("tv-schedule-for-today.pdf")
 
    let pdfDoc: PDFDocument? = PDFDocument(url: url)
    //var pageCount = 0  // for future use with custom pagination
    
    let page: PDFPage? = pdfDoc!.page(at: 0)!
    
    var mediaBox: CGRect = page!.bounds(for: .mediaBox)
    
    guard let currentContext = CGContext(url as CFURL, mediaBox: &mediaBox, nil) else {
        return
    }
    var context: CGContext? = currentContext
    
    let nscontext = NSGraphicsContext(cgContext: context!, flipped: false)
    NSGraphicsContext.current = nscontext

    context!.beginPDFPage(nil)
    
    do {
        page!.draw(with: .mediaBox, to: context!)

        let attributes = [
              NSAttributedString.Key.font: NSFont.boldSystemFont(ofSize: 36)
            ]
        let text = "I'm a simpler PDF!"
        text.draw(at: CGPoint(x: 100, y: 100), withAttributes: attributes)
    
    }

    context!.endPDFPage()

    NSGraphicsContext.current = nil

    context!.closePDF()
    
    context = nil

}
0

There are 0 best solutions below