Display and manipulate PDF documents using PDFKit. Use when embedding PDFView to show PDF files, creating or modifying PDFDocument instances, adding annotations (highlights, notes, signature widgets), extracting text with PDFSelection, navigating pages, generating thumbnails, filling PDF forms, or wrapping PDFView in SwiftUI.
91%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Passed
No findings from the security scan
Display, navigate, search, annotate, and manipulate PDF documents with PDFView, PDFDocument, PDFPage, PDFAnnotation, and PDFSelection.
PDFView display, scaling, navigation, and observation for the actual product surface.PDFDocument initialization succeeds or that a protected document is unlocked.PDFDocument(url:) and PDFDocument(data:) are failable initializers.
// WRONG
let document = PDFDocument(url: url)!
// CORRECT
guard let document = PDFDocument(url: url) else { return }Without autoScales, the PDF renders at its native resolution.
// WRONG
pdfView.document = document
// CORRECT
pdfView.autoScales = true
pdfView.document = documentPDF page coordinates have origin at the bottom-left with Y increasing upward -- opposite of UIKit.
// WRONG: UIKit coordinates
let bounds = CGRect(x: 50, y: 50, width: 200, height: 30)
// CORRECT: PDF coordinates (origin bottom-left)
let pageBounds = page.bounds(for: .mediaBox)
let pdfY = pageBounds.height - 50 - 30
let bounds = CGRect(x: 50, y: pdfY, width: 200, height: 30)PDFKit classes are not thread-safe. All mutations must occur on @MainActor.
// WRONG: Modifying PDFKit objects from background tasks
Task.detached { page.addAnnotation(annotation) }
// CORRECT: Perform mutations on @MainActor
@MainActor
func addNote(to page: PDFPage, annotation: PDFAnnotation) {
page.addAnnotation(annotation)
}PDFDocument is a reference type. Use identity (!==).
// WRONG: Always replaces document
func updateUIView(_ pdfView: PDFView, context: Context) {
pdfView.document = document
}
// CORRECT
func updateUIView(_ pdfView: PDFView, context: Context) {
if pdfView.document !== document {
pdfView.document = document
}
}PDFDocument init uses optional binding, not force-unwrappdfView.autoScales = true set for proper initial displaypageCount before accessdisplayMode and displayDirection configured to match designisLocked / unlock(withPassword:)!== identity check in updateUIViewPDFViewPageChanged notification observed for page trackingPDFThumbnailView.pdfView linked to the main PDFViewbeginFindString with delegatewrite(to:withOptions:) when encryption neededthienqo/ios-skills
6bf8b62
Canonical home
since May 23, 2026
Also appears in
on Sep 6, 2026
since May 22, 2026
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.