I need to render a PDF and then make it downloadable to the mobile device. I can generate the PDF but I'm unsure how to configure the download aspect. I have the following code:
let renderer = UIGraphicsPDFRenderer(bounds: CGRect(x: 0, y: 0, width: 612, height: 792))
let pdf = renderer.pdfData { (context) in
context.beginPage()
let text = "Test" as NSString
text.draw(in: CGRect(x: 0, y: 0, width: 100, height: 25))
Most of what I wanted to say has already been covered in responses to this forums post above, but here is a summary of my thoughts about this question:
Quartz 2D Programming Guide: Graphics Contexts: Creating a PDF Graphics Context https://developer.apple.com/library/archive/documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_context/dq_context.html#//apple_ref/doc/uid/TP30001066-CH203-TPXREF118
- this document talks about the general concepts involved in creating a PDF. As it has been observed above, this document uses Objective-C language. However, you should be able to get the idea of the general flow of the APIs. And, you can look up the Objective-C versions of the APIs on our website and then display the Swift equivalents using the language pop-up menu in the top right of each page.
The APIs described in the "Creating a PDF Graphics Context" section are documented here:
Core Graphics: CGPDFContext https://developer.apple.com/documentation/coregraphics/cgpdfcontext/
- you can use the language popup at the top of each page to select the language - Objective-C or Swift.
Those are the APIs for creating PDF files. When creating PDF files, you use the Core Graphics drawing APIs for drawing content. Please see, the following documentation for more information about Core Graphics.
Core Graphics https://developer.apple.com/documentation/coregraphics/
Quartz 2D Programming Guide https://developer.apple.com/library/archive/documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/Introduction/Introduction.html
For drawing text, the current recommendation is to use TextKit (https://developer.apple.com/documentation/appkit/textkit). There is also the lower level Core Text API (https://developer.apple.com/documentation/coretext/), also mentioned above, but you should only consider using that if you cannot do something you want to do using TextKit.
We also offer the PDFKit APIs (https://developer.apple.com/documentation/pdfkit/). They are mainly for displaying PDF files in PDFViews, but the also offer some APIs for editing PDF files. Such as, for example, the ability to adjust the properties of pages and to move pages around in documents.
The PDFKit APIs also offer a way to create PDFPages from UIImages or NSImages (https://developer.apple.com/documentation/pdfkit/pdfpage/init(image:)), but if you want to have scalable vector graphics in your PDF files you should use the Core Graphics APIs to create your PDF files.
If you are interested in creating PDFs from your SwiftUI views, you can use the PDFPage init(image:) method together with SwiftUI's ImageRenderer (https://developer.apple.com/documentation/swiftui/imagerenderer). The idea here is to use the ImageRenderer to create images that you use to initialize PDFPages and then add those pages to a PDFDocument.
Using the PDFPage init(image:) method may seem like a simple and convenient way to go, but I would be remis if I didn't provide the following warnings:
- creating pages from raster images will create large PDF files containing raster images and will defeat scalable vector graphics quality of PDFs that many users expect when using PDF files. When scaling pages and viewing them at different resolutions, blocky edges in the graphics may result.
- PDF files containing pages created from raster images will be substantially larger than PDF files created using Core Graphics and TextKit drawing routines.
- be sure to test in every version of the operating system where you expect your app will be deployed - previously, I have received some bug reports about this method not working as expected.
- you will need to figure out your own strategies for formatting your SwiftUI views when drawing to an ImageRenderer so that they will be sized appropriately for PDF pages.
For better quality PDF files, I recommend using the Core Graphics CGPDFContext based routines together with Core Graphics and TextKit.