Artem Poluektov
Posted on March 19, 2023
This is the third article about Apple’s PDFkit featuring in-code document creation and pages operations.
- First article is about PDFKit basics & Ink annotations
- Second is about PencilKit, Text annotations & auto-saving
Create PDF Document using Swift
In case you need to create a new PDF file on iOS device you won’t actually need to use PDFKit at all. There are few simple UIKit methods for that.
First, you need to create UIGraphicsPDFRendererFormat
object to provide PDF document metadata such as author, etc.
let format = UIGraphicsPDFRendererFormat()
let metaData = [
kCGPDFContextTitle: "Hello, World!",
kCGPDFContextAuthor: "John Doe"
]
format.documentInfo = metaData as [String: Any]
You’ll find a full list of available metadata parameters in CoreGraphics framework reference documentation, just start typing kCGPDF
in your code in Xcode.
Second, we need to calculate PDF page dimensions. PDF documents use a default resolution of 72 DPI. Page dimensions would be:
// US Letter
Width: 8.5 inches * 72 DPI = 612 points
Height: 11 inches * 72 DPI = 792 points
// A4 would be [W x H] 595 x 842 points
After doing this math, we need to instantiate UIGraphicsPDFRenderer
object, which is responsible of document rendering.
let pageRect = CGRect(x: 0, y: 0, width: 595, height: 842)
let renderer = UIGraphicsPDFRenderer(bounds: pageRect,
format: format)
Third, to start drawing just call .pdfData method of your renderer:
let data = renderer.pdfData { (context) in
// Perform your drawing here
}
You could call every drawing method of CoreGraphics
framework here. But, first you need to create new PDF page by calling context.beginPage()
. Call this code every time you need to start new page.
To draw a simple “Hello, world!” text use this code example:
let data = renderer.pdfData { (context) in
context.beginPage()
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center
let attributes = [
NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 14),
NSAttributedString.Key.paragraphStyle: paragraphStyle
]
let text = "Hello, World!"
let textRect = CGRect(x: 100, // left margin
y: 100, // top margin
width: 200,
height: 20)
text.draw(in: textRect, withAttributes: attributes)
}
What’s just happened?
- We started new PDF page.
- Created new
NSParagraphStyle
object to add.center
alignment to our text. - Created
attributes
dictionary containing font and paragraph style. - Created text String.
- Created
textRect
struct describing specific rect where our text would be drawn. - Called
.draw
method of string object.
That’s it. Easy, right? Just provide your own attributes like color, font, etc.
Finally, we must save out PDF context to file on device. As rendered would return Data
object, we have 2 ways of saving our document:
- Initializing
PDFKit
'sPDFDocument(data:)
object and writing it to file
let pdfDocument = PDFDocument(data: data)
let path = PATH_TO_DESIRED_FILE
pdfDocument.write(to: path)
- Using
UIGraphicsPDFRendered
's methodwritePDF
instead ofpdfData
in third step. Let's replace
let data = renderer.pdfData { (context) in
with
let url = URL_TO_DESIRED_FILE
try? rendered.writePDF(to: url) { (context) in
...
}
You must add try?
call because writing operation is throwable.
Insert page to PDF document
To add or remove pages to/from PDF document we need to use Apple’s PDFKit
methods.
First, you need to initialize 2 PDF documents. One where the page would be inserted, and another from which we’ll take the page to insert.
let firstPDFDocument = PDFDocument(url: URL_TO_YOUR_FIRST_DOC)
let secondPDFDocument = PDFDocument(url: URL_TO_YOUR_SECOND_DOC)
Second, locate the page you want to insert and insert it at desired location:
// let's assume we want to insert 5th page of 2nd doc to 1st doc
let page = secondDocument.page(at: 5)
// And insert this page as first
firstDocument.insert(page, at: 0)
Don’t forget to save your document after insertion:
firstDocument.write(to: URL_TO_YOUR_FIRST_DOC)
Remove page from PDF Document
Removing pages is easy as well:
let pdfDocument = PDFDocument(url: URL_TO_YOUR_DOC)
pdfDocument.removePage(at: 0) // removing the first page
firstDocument.write(to: URL_TO_YOUR_DOC)
That’s it.
Posted on March 19, 2023
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.