Convert a UIImage to PDF in Swift

PDFKit was introduced with iOS 11, giving much respite to developers who earlier had to deal with C++ for PDF rendering in their applications.

The PDFKit allows us to create, modify, and display PDFs in our applications.
The goal of this article is to convert UIImage(s) to a PDF using Swift.

We will be using the iOS 13 VisionKit, which has a document camera scanner. We’ve already discussed the implementation of VisionKit’s document scanner here.

Plan of action

  • Scanning images using VisionKit’s document scanner

  • Converting them into a PDF Document

  • Saving the PDF using FileManager

  • Displaying the PDF in a PDFView

What we’ll achieve

PDFKit: What’s In It?

PDFKit consists of the following classes:

  1. PDFPage: A PDFPage is responsible for rendering a single page of the PDF. Typically a PDFPage requires an image in its initializer method.

  2. PDFDocument: An instance of this class contains the complete PDF's data and hosts every PDFPage.

  3. PDFView: This is responsible for displaying the PDF in our application's UI. It has the following properties that can be customized:

  • PDFDisplayMode: This can be either singlePagesinglePageContinuous,twoUp, or twoUpContinuous

  • PDFDisplayDirection: The PDF pages can be either horizontal or vertical scrolling

4. PDFThumbnailView: This is used for displaying thumbnail previews of the PDF pages.

There are other classes as well, such as PDFOutline and PDFSelection(for selecting texts in a PDF), which we’re not covering in this particular article.

To get the full content of the PDF, use the string property on the PDFDocument. To get the full content of a PDFPage, use the attributedString property.

UIImage to PDFPage to PDFDocument

let pdfDocument = PDFDocument()
for i in 0 ..< scan.pageCount {
if let image = scan.imageOfPage(at: i).resize(toWidth: 250){
let pdfPage = PDFPage(image: image)
pdfDocument.insert(pdfPage!, at: i)

This creates our PDF. We have resized the scanned images using a resize extension function (available at the end of this article).

Saving PDFDocument to the documents directory

In order to save the PDFDocument, retrieve the raw data and write it to the documents directory URL as shown below:

let data = pdfDocument.dataRepresentation()
let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let docURL = documentDirectory.appendingPathComponent("Scanned-Docs.pdf")
try data?.write(to: docURL)
}catch(let error){
print("error is \(error.localizedDescription)")

Displaying In PDFView

Finally, we can embed the PDFView in the parent view and show the saved PDF in it:

let pdfView = PDFView()
pdfView.translatesAutoresizingMaskIntoConstraints = false
let docURL = documentDirectory.appendingPathComponent("Scanned-Docs.pdf")
if fileManager.fileExists(atPath: docURL.path){
pdfView.document = PDFDocument(url: docURL)

That’s it. We are done converting a batch of UIImages into a PDF file.
The full source code is available here.