0

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

}
Joe Bell
  • 13
  • 3
  • What are you drawing text over? – El Tomato Nov 25 '21 at 07:40
  • You are not creating an `NSImage` object, with which you should create `PDFPage` object. – El Tomato Nov 25 '21 at 07:49
  • @El Tomato, I don't understand the question. The text should be getting drawn inside the CGRect, yes? no? There is nothing else going on that page. No graphics at all, except eventually I'd like to have borders around the text. But in this example, just plain text. – Joe Bell Nov 25 '21 at 07:49
  • Yes. Yes it does. Here's the funny thing though. I visited that page earlier, but apparently I didn't get it exactly right. There were some initialization issues with the pdf document, but much more important, I completely overlooked these lines: let nscontext = NSGraphicsContext(cgContext: context!, flipped: false) NSGraphicsContext.current = nscontext. So I neglected to wire in the NSGraphics context. Once I did that, it worked perfectly. Thanks!! – Joe Bell Nov 25 '21 at 13:27
  • But @Willeke, how do I give you credit for the answer? – Joe Bell Nov 25 '21 at 13:31
  • I'm just voting to close this question as duplicate. Give credit to rob mayoff by upvoting the answer. – Willeke Nov 26 '21 at 12:37

0 Answers0