Xcode 13 OSX SwiftUI - What is the recommended way to create a pdf

What is the currently recommended way to create a pdf document in Xcode 13 for Mac OSX using Swift and SwiftUI?

I find very little documentation on this. Most articles are for IOS. Only some articles for OSX from many, many years back. With SwiftUI, it will become common place for our code to be used interchangeable in multiple operating systems. And pdf is pretty much the way to go with document and report printouts.

Please point me in the right direction. Maybe I was just not looking in the right place.

My pdf documents are created without any problem for IOS and Ipad using CG and PDFKit functions.

But the same code did not work for the Mac app. So I modified the UIFont to NSFont, etc. Context functions are different. Moved to using CoreText for the attributed string placements. ( CTFrame )

But the strange stuff is the Y point placement that is correct for IOS but seems to be reversed for OSX.

So this was when I thought I must be using some old stuff that is not meant for today's work.

Brief Example below:

func pdf_placeText_CT( cgContext: CGContext, pageSize: CGSize, text: String, width: CGFloat, height: CGFloat, font: NSFont, alignment: String, xPoint: CGFloat, yPoint: CGFloat ) {
     
  let pointY = pageSize.height - yPoint  // for some reason we have to flip the vertical. Strange.

  let paragraphstyle = NSMutableParagraphStyle()
     
    if ( alignment == "R" ) {
      paragraphstyle.alignment = .right
    } else if ( alignment == "C" ) {
      paragraphstyle.alignment = .center
    } else {
      paragraphstyle.alignment = .left
    }
     
  let attributedText = NSAttributedString(string: text, attributes: [
      NSAttributedString.Key.font      : font ,
      NSAttributedString.Key.paragraphStyle : paragraphstyle
     ])
     
  let stringSize = attributedText.size()
  let stringRect = CGRect(x: xPoint, y: pointY, width: stringSize.width+5, height: stringSize.height+5)
  let stringPath = CGPath(rect: stringRect, transform: nil)

   //attributedText.draw(in: stringRect)
   
  let textFrame = CTFramesetterCreateWithAttributedString(attributedText)
  let textRange = CFRangeMake(0, attributedText.length)
  var pageRange = CFRange()
  CTFramesetterSuggestFrameSizeWithConstraints(textFrame, textRange, nil, pageSize, &pageRange)
   
  let frame = CTFramesetterCreateFrame(textFrame, pageRange, stringPath, nil)
   
  CTFrameDraw(frame, cgContext )
   
 }

Replies

I have found the basis for how to solve the pdf creation problems.

From 2012, Apple documentation on IOS Drawing Concepts

https://developer.apple.com/library/archive/documentation/2DDrawing/Conceptual/DrawingPrintingiOS/GraphicsDrawingOverview/GraphicsDrawingOverview.html

And just in case you cannot find it, here was the important part for me. It describes the coordinate system and how it is used for placement of text and graphics.

An upper-left-origin coordinate system (ULO), in which the origin of drawing operations is at the upper-left corner of the drawing area, with positive values extending downward and to the right. The default coordinate system used by the UIKit and Core Animation frameworks is ULO-based.

A lower-left-origin coordinate system (LLO), in which the origin of drawing operations is at the lower-left corner of the drawing area, with positive values extending upward and to the right. The default coordinate system used by Core Graphics framework is LLO-based.