{"id":"180fee10-ced0-4053-8266-5a2d49960389","shortId":"pBScxG","kind":"skill","title":"pdfkit","tagline":"Display and manipulate PDF documents using PDFKit. Use when embedding PDFView to show PDF files, creating or modifying PDFDocument instances, adding annotations (highlights, notes, signatures), extracting text with PDFSelection, navigating pages, generating thumbnails, filling PD","description":"# PDFKit\n\nDisplay, navigate, search, annotate, and manipulate PDF documents with\n`PDFView`, `PDFDocument`, `PDFPage`, `PDFAnnotation`, and `PDFSelection`.\nTargets Swift 6.3 / iOS 26+.\n\n## Contents\n\n- [Setup](#setup)\n- [Displaying PDFs](#displaying-pdfs)\n- [Loading Documents](#loading-documents)\n- [Page Navigation](#page-navigation)\n- [Text Search and Selection](#text-search-and-selection)\n- [Annotations](#annotations)\n- [Thumbnails](#thumbnails)\n- [SwiftUI Integration](#swiftui-integration)\n- [Common Mistakes](#common-mistakes)\n- [Review Checklist](#review-checklist)\n- [References](#references)\n\n## Setup\n\nPDFKit requires no entitlements or Info.plist entries.\n\n```swift\nimport PDFKit\n```\n\n**Platform availability:** iOS 11+, iPadOS 11+, Mac Catalyst 13.1+,\nmacOS 10.4+, tvOS 11+, visionOS 1.0+.\n\n## Displaying PDFs\n\n`PDFView` is a `UIView` subclass that renders PDF content, handles zoom,\nscroll, text selection, and page navigation out of the box.\n\n```swift\nimport PDFKit\nimport UIKit\n\nclass PDFViewController: UIViewController {\n    let pdfView = PDFView()\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        pdfView.frame = view.bounds\n        pdfView.autoresizingMask = [.flexibleWidth, .flexibleHeight]\n        view.addSubview(pdfView)\n\n        pdfView.autoScales = true\n        pdfView.displayMode = .singlePageContinuous\n        pdfView.displayDirection = .vertical\n\n        if let url = Bundle.main.url(forResource: \"sample\", withExtension: \"pdf\") {\n            pdfView.document = PDFDocument(url: url)\n        }\n    }\n}\n```\n\n### Display Modes\n\n| Mode | Behavior |\n|---|---|\n| `.singlePage` | One page at a time |\n| `.singlePageContinuous` | Pages stacked vertically, scrollable |\n| `.twoUp` | Two pages side by side |\n| `.twoUpContinuous` | Two-up with continuous scrolling |\n\n### Scaling and Appearance\n\n```swift\npdfView.autoScales = true\npdfView.minScaleFactor = pdfView.scaleFactorForSizeToFit\npdfView.maxScaleFactor = 4.0\n\npdfView.displaysPageBreaks = true\npdfView.pageShadowsEnabled = true\npdfView.interpolationQuality = .high\n```\n\n## Loading Documents\n\n`PDFDocument` loads from a URL, `Data`, or can be created empty.\n\n```swift\nlet fileDoc = PDFDocument(url: fileURL)\nlet dataDoc = PDFDocument(data: pdfData)\nlet emptyDoc = PDFDocument()\n```\n\n### Password-Protected PDFs\n\n```swift\nguard let document = PDFDocument(url: url) else { return }\nif document.isLocked {\n    if !document.unlock(withPassword: userPassword) {\n        // Show password prompt\n    }\n}\n```\n\n### Saving and Page Manipulation\n\n```swift\ndocument.write(to: outputURL)\ndocument.write(to: outputURL, withOptions: [\n    .ownerPasswordOption: \"ownerPass\", .userPasswordOption: \"userPass\"\n])\nlet data = document.dataRepresentation()\n\n// Pages (0-based)\nlet count = document.pageCount\ndocument.insert(PDFPage(), at: count)\ndocument.removePage(at: 2)\ndocument.exchangePage(at: 0, withPageAt: 3)\n```\n\n## Page Navigation\n\n`PDFView` provides built-in navigation with history tracking.\n\n```swift\n// Go to a specific page\nif let page = pdfView.document?.page(at: 5) {\n    pdfView.go(to: page)\n}\n\n// Sequential navigation\npdfView.goToNextPage(nil)\npdfView.goToPreviousPage(nil)\npdfView.goToFirstPage(nil)\npdfView.goToLastPage(nil)\n\n// Check navigation state\nif pdfView.canGoToNextPage { /* ... */ }\n\n// History navigation\nif pdfView.canGoBack { pdfView.goBack(nil) }\n\n// Go to a specific point on a page\nlet destination = PDFDestination(page: page, at: CGPoint(x: 0, y: 500))\npdfView.go(to: destination)\n```\n\n### Observing Page Changes\n\n```swift\nNotificationCenter.default.addObserver(\n    self, selector: #selector(pageChanged),\n    name: .PDFViewPageChanged, object: pdfView\n)\n\n@objc func pageChanged(_ notification: Notification) {\n    guard let page = pdfView.currentPage,\n          let doc = pdfView.document else { return }\n    let index = doc.index(for: page)\n    pageLabel.text = \"Page \\(index + 1) of \\(doc.pageCount)\"\n}\n```\n\n## Text Search and Selection\n\n### Synchronous Search\n\n```swift\nlet results: [PDFSelection] = document.findString(\n    \"search term\", withOptions: [.caseInsensitive]\n)\n```\n\n### Asynchronous Search\n\nUse `PDFDocumentDelegate` for background searches on large documents.\nImplement `didMatchString(_:)` to receive each match and\n`documentDidEndDocumentFind(_:)` for completion.\n\n### Incremental Search and Find Interaction\n\n```swift\n// Find next match from current selection\nlet next = document.findString(\"term\", fromSelection: current, withOptions: [.caseInsensitive])\n\n// System find bar (iOS 16+)\npdfView.isFindInteractionEnabled = true\n```\n\n### Text Extraction\n\n```swift\nlet fullText = document.string                          // Entire document\nlet pageText = document.page(at: 0)?.string             // Single page\nlet attributed = document.page(at: 0)?.attributedString  // With formatting\n\n// Region-based extraction\nif let page = document.page(at: 0) {\n    let selection = page.selection(for: CGRect(x: 50, y: 50, width: 400, height: 200))\n    let text = selection?.string\n}\n```\n\n### Highlighting Search Results\n\n```swift\nlet results = document.findString(\"important\", withOptions: [.caseInsensitive])\nfor selection in results { selection.color = .yellow }\npdfView.highlightedSelections = results\n\nif let first = results.first {\n    pdfView.setCurrentSelection(first, animate: true)\n    pdfView.go(to: first)\n}\n```\n\n## Annotations\n\nAnnotations are created with `PDFAnnotation(bounds:forType:withProperties:)`\nand added to a `PDFPage`.\n\n### Highlight Annotation\n\n```swift\nfunc addHighlight(to page: PDFPage, selection: PDFSelection) {\n    let highlight = PDFAnnotation(\n        bounds: selection.bounds(for: page),\n        forType: .highlight, withProperties: nil\n    )\n    highlight.color = UIColor.yellow.withAlphaComponent(0.5)\n    page.addAnnotation(highlight)\n}\n```\n\n### Text Note Annotation\n\n```swift\nlet note = PDFAnnotation(\n    bounds: CGRect(x: 100, y: 700, width: 30, height: 30),\n    forType: .text, withProperties: nil\n)\nnote.contents = \"This is a sticky note.\"\nnote.color = .systemYellow\nnote.iconType = .comment\npage.addAnnotation(note)\n```\n\n### Free Text Annotation\n\n```swift\nlet freeText = PDFAnnotation(\n    bounds: CGRect(x: 50, y: 600, width: 300, height: 40),\n    forType: .freeText, withProperties: nil\n)\nfreeText.contents = \"Added commentary\"\nfreeText.font = UIFont.systemFont(ofSize: 14)\nfreeText.fontColor = .darkGray\npage.addAnnotation(freeText)\n```\n\n### Link Annotation\n\n```swift\nlet link = PDFAnnotation(\n    bounds: CGRect(x: 50, y: 500, width: 200, height: 20),\n    forType: .link, withProperties: nil\n)\nlink.url = URL(string: \"https://example.com\")\npage.addAnnotation(link)\n\n// Internal page link\nlink.destination = PDFDestination(page: targetPage, at: .zero)\n```\n\n### Removing Annotations\n\n```swift\nfor annotation in page.annotations {\n    page.removeAnnotation(annotation)\n}\n```\n\n### Annotation Subtypes Reference\n\n| Subtype | Constant | Purpose |\n|---|---|---|\n| Highlight | `.highlight` | Text markup (yellow highlight) |\n| Underline | `.underline` | Text markup (underline) |\n| StrikeOut | `.strikeOut` | Text markup (strikethrough) |\n| Text | `.text` | Sticky note icon |\n| FreeText | `.freeText` | Inline text block |\n| Ink | `.ink` | Freehand drawing paths |\n| Link | `.link` | URL or page destination |\n| Line | `.line` | Straight line with endpoints |\n| Square | `.square` | Rectangle shape |\n| Circle | `.circle` | Ellipse shape |\n| Stamp | `.stamp` | Rubber stamp (Approved, etc.) |\n| Widget | `.widget` | Form element (text field, checkbox) |\n\n## Thumbnails\n\n### PDFThumbnailView\n\n`PDFThumbnailView` shows a strip of page thumbnails linked to a `PDFView`.\n\n```swift\nlet thumbnailView = PDFThumbnailView()\nthumbnailView.pdfView = pdfView\nthumbnailView.thumbnailSize = CGSize(width: 60, height: 80)\nthumbnailView.layoutMode = .vertical\nthumbnailView.translatesAutoresizingMaskIntoConstraints = false\nview.addSubview(thumbnailView)\n```\n\n### Generating Thumbnails Programmatically\n\n```swift\nlet thumbnail = page.thumbnail(of: CGSize(width: 120, height: 160), for: .mediaBox)\n\n// All pages\nlet thumbnails = (0..<document.pageCount).compactMap {\n    document.page(at: $0)?.thumbnail(of: CGSize(width: 120, height: 160), for: .mediaBox)\n}\n```\n\n## SwiftUI Integration\n\nWrap `PDFView` in a `UIViewRepresentable` for SwiftUI.\n\n```swift\nimport SwiftUI\nimport PDFKit\n\nstruct PDFKitView: UIViewRepresentable {\n    let document: PDFDocument\n\n    func makeUIView(context: Context) -> PDFView {\n        let pdfView = PDFView()\n        pdfView.autoScales = true\n        pdfView.displayMode = .singlePageContinuous\n        pdfView.document = document\n        return pdfView\n    }\n\n    func updateUIView(_ pdfView: PDFView, context: Context) {\n        if pdfView.document !== document {\n            pdfView.document = document\n        }\n    }\n}\n```\n\n### Usage\n\n```swift\nstruct DocumentScreen: View {\n    let url: URL\n\n    var body: some View {\n        if let document = PDFDocument(url: url) {\n            PDFKitView(document: document)\n                .ignoresSafeArea()\n        } else {\n            ContentUnavailableView(\"Unable to load PDF\", systemImage: \"doc.questionmark\")\n        }\n    }\n}\n```\n\nFor interactive wrappers with page tracking, annotation hit detection, and\ncoordinator patterns, see [references/pdfkit-patterns.md](references/pdfkit-patterns.md).\n\n### Page Overlays (iOS 16+)\n\n`PDFPageOverlayViewProvider` places UIKit views on top of individual pages\nfor interactive controls or custom rendering beyond standard annotations.\n\n```swift\nclass OverlayProvider: NSObject, PDFPageOverlayViewProvider {\n    func pdfView(_ view: PDFView, overlayViewFor page: PDFPage) -> UIView? {\n        let overlay = UIView()\n        // Add custom subviews\n        return overlay\n    }\n}\n\npdfView.pageOverlayViewProvider = overlayProvider\n```\n\n## Common Mistakes\n\n### DON'T: Force-unwrap PDFDocument init\n\n`PDFDocument(url:)` and `PDFDocument(data:)` are failable initializers.\n\n```swift\n// WRONG\nlet document = PDFDocument(url: url)!\n\n// CORRECT\nguard let document = PDFDocument(url: url) else { return }\n```\n\n### DON'T: Forget autoScales on PDFView\n\nWithout `autoScales`, the PDF renders at its native resolution.\n\n```swift\n// WRONG\npdfView.document = document\n\n// CORRECT\npdfView.autoScales = true\npdfView.document = document\n```\n\n### DON'T: Ignore PDF coordinate system in annotations\n\nPDF page coordinates have origin at the bottom-left with Y increasing\nupward -- opposite of UIKit.\n\n```swift\n// WRONG: UIKit coordinates\nlet bounds = CGRect(x: 50, y: 50, width: 200, height: 30)\n\n// CORRECT: PDF coordinates (origin bottom-left)\nlet pageBounds = page.bounds(for: .mediaBox)\nlet pdfY = pageBounds.height - 50 - 30\nlet bounds = CGRect(x: 50, y: pdfY, width: 200, height: 30)\n```\n\n### DON'T: Modify annotations on a background thread\n\nPDFKit classes are not thread-safe.\n\n```swift\n// WRONG\nDispatchQueue.global().async { page.addAnnotation(annotation) }\n\n// CORRECT\nDispatchQueue.main.async { page.addAnnotation(annotation) }\n```\n\n### DON'T: Compare PDFDocument with == in UIViewRepresentable\n\n`PDFDocument` is a reference type. Use identity (`!==`).\n\n```swift\n// WRONG: Always replaces document\nfunc updateUIView(_ pdfView: PDFView, context: Context) {\n    pdfView.document = document\n}\n\n// CORRECT\nfunc updateUIView(_ pdfView: PDFView, context: Context) {\n    if pdfView.document !== document {\n        pdfView.document = document\n    }\n}\n```\n\n## Review Checklist\n\n- [ ] `PDFDocument` init uses optional binding, not force-unwrap\n- [ ] `pdfView.autoScales = true` set for proper initial display\n- [ ] Page indices checked against `pageCount` before access\n- [ ] `displayMode` and `displayDirection` configured to match design\n- [ ] Annotations use PDF coordinate space (origin bottom-left, Y up)\n- [ ] All PDFKit mutations happen on the main thread\n- [ ] Password-protected PDFs handled with `isLocked` / `unlock(withPassword:)`\n- [ ] SwiftUI wrapper uses `!==` identity check in `updateUIView`\n- [ ] `PDFViewPageChanged` notification observed for page tracking\n- [ ] `PDFThumbnailView.pdfView` linked to the main `PDFView`\n- [ ] Large-document search uses async `beginFindString` with delegate\n- [ ] Saved documents use `write(to:withOptions:)` when encryption needed\n\n## References\n\n- Extended patterns (forms, watermarks, merging, printing, overlays, outlines, custom drawing): [references/pdfkit-patterns.md](references/pdfkit-patterns.md)\n- [PDFKit framework](https://sosumi.ai/documentation/pdfkit)\n- [PDFView](https://sosumi.ai/documentation/pdfkit/pdfview)\n- [PDFDocument](https://sosumi.ai/documentation/pdfkit/pdfdocument)\n- [PDFPage](https://sosumi.ai/documentation/pdfkit/pdfpage)\n- [PDFAnnotation](https://sosumi.ai/documentation/pdfkit/pdfannotation)\n- [PDFSelection](https://sosumi.ai/documentation/pdfkit/pdfselection)\n- [PDFThumbnailView](https://sosumi.ai/documentation/pdfkit/pdfthumbnailview)\n- [PDFPageOverlayViewProvider](https://sosumi.ai/documentation/pdfkit/pdfpageoverlayviewprovider)\n- [Adding Widgets to a PDF Document](https://sosumi.ai/documentation/pdfkit/adding-widgets-to-a-pdf-document)\n- [Adding Custom Graphics to a PDF](https://sosumi.ai/documentation/pdfkit/adding-custom-graphics-to-a-pdf)","tags":["pdfkit","swift","ios","skills","dpearson2699","accessibility","agent-skills","ai-coding","apple","claude-code","codex-skills","cursor-skills"],"capabilities":["skill","source-dpearson2699","skill-pdfkit","topic-accessibility","topic-agent-skills","topic-ai-coding","topic-apple","topic-claude-code","topic-codex-skills","topic-cursor-skills","topic-ios","topic-ios-development","topic-liquid-glass","topic-localization","topic-mapkit"],"categories":["swift-ios-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/dpearson2699/swift-ios-skills/pdfkit","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add dpearson2699/swift-ios-skills","source_repo":"https://github.com/dpearson2699/swift-ios-skills","install_from":"skills.sh"}},"qualityScore":"0.684","qualityRationale":"deterministic score 0.68 from registry signals: · indexed on github topic:agent-skills · 468 github stars · SKILL.md body (13,193 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-04-22T00:53:44.001Z","embedding":null,"createdAt":"2026-04-18T22:01:09.643Z","updatedAt":"2026-04-22T00:53:44.001Z","lastSeenAt":"2026-04-22T00:53:44.001Z","tsv":"'/documentation/pdfkit)':1299 '/documentation/pdfkit/adding-custom-graphics-to-a-pdf)':1345 '/documentation/pdfkit/adding-widgets-to-a-pdf-document)':1336 '/documentation/pdfkit/pdfannotation)':1315 '/documentation/pdfkit/pdfdocument)':1307 '/documentation/pdfkit/pdfpage)':1311 '/documentation/pdfkit/pdfpageoverlayviewprovider)':1327 '/documentation/pdfkit/pdfselection)':1319 '/documentation/pdfkit/pdfthumbnailview)':1323 '/documentation/pdfkit/pdfview)':1303 '0':308,322,389,507,515,528,844,849 '0.5':612 '1':430 '1.0':131 '10.4':127 '100':625 '11':120,122,129 '120':835,854 '13.1':125 '14':675 '16':492,954 '160':837,856 '2':319 '20':695 '200':541,693,1090,1118 '26':57 '3':324 '30':629,631,1092,1109,1120 '300':662 '4.0':232 '40':664 '400':539 '5':348 '50':535,537,658,689,1086,1088,1108,1114 '500':391,691 '6.3':55 '60':816 '600':660 '700':627 '80':818 'access':1209 'ad':22,585,670,1328,1337 'add':989 'addhighlight':593 'alway':1162 'anim':570 'annot':23,41,85,86,575,576,590,617,650,681,716,719,723,724,942,972,1060,1124,1141,1145,1217 'appear':225 'approv':785 'async':1139,1269 'asynchron':448 'attribut':512 'attributedstr':516 'autoscal':1032,1036 'avail':118 'background':453,1127 'bar':490 'base':309,521 'beginfindstr':1270 'behavior':198 'beyond':970 'bind':1191 'block':755 'bodi':915 'bottom':1069,1098,1224 'bottom-left':1068,1097,1223 'bound':581,602,622,655,686,1083,1111 'box':154 'built':330 'built-in':329 'bundle.main.url':186 'caseinsensit':447,487,555 'catalyst':124 'cgpoint':387 'cgrect':533,623,656,687,1084,1112 'cgsize':814,833,852 'chang':397 'check':362,1205,1249 'checkbox':793 'checklist':100,103,1186 'circl':777,778 'class':160,974,1130 'comment':645 'commentari':671 'common':94,97,996 'common-mistak':96 'compactmap':846 'compar':1148 'complet':467 'configur':1213 'constant':728 'content':58,142 'contentunavailableview':929 'context':881,882,899,900,1169,1170,1178,1179 'continu':221 'control':966 'coordin':946,1057,1063,1081,1095,1220 'correct':1020,1048,1093,1142,1173 'count':311,316 'creat':17,250,578 'current':478,485 'custom':968,990,1291,1338 'darkgray':677 'data':246,261,305,1009 'datadoc':259 'deleg':1272 'design':1216 'destin':382,394,766 'detect':944 'didmatchstr':459 'dispatchqueue.global':1138 'dispatchqueue.main.async':1143 'display':2,38,61,64,132,195,1202 'displaydirect':1212 'displaying-pdf':63 'displaymod':1210 'doc':418 'doc.index':424 'doc.pagecount':432 'doc.questionmark':935 'document':6,45,67,70,240,273,457,502,877,892,903,905,920,925,926,1016,1023,1047,1052,1164,1172,1182,1184,1266,1274,1333 'document.datarepresentation':306 'document.exchangepage':320 'document.findstring':443,482,552 'document.insert':313 'document.islocked':280 'document.page':505,513,526,847 'document.pagecount':312,845 'document.removepage':317 'document.string':500 'document.unlock':282 'document.write':293,296 'documentdidenddocumentfind':465 'documentscreen':909 'draw':759,1292 'element':790 'ellips':779 'els':277,420,928,1027 'embed':11 'empti':251 'emptydoc':264 'encrypt':1280 'endpoint':772 'entir':501 'entitl':110 'entri':113 'etc':786 'example.com':703 'extend':1283 'extract':27,496,522 'failabl':1011 'fals':822 'field':792 'file':16 'filedoc':254 'fileurl':257 'fill':35 'find':471,474,489 'first':566,569,574 'flexibleheight':174 'flexiblewidth':173 'forc':1001,1194 'force-unwrap':1000,1193 'forget':1031 'form':789,1285 'format':518 'forresourc':187 'fortyp':582,606,632,665,696 'framework':1296 'free':648 'freehand':758 'freetext':653,666,679,751,752 'freetext.contents':669 'freetext.font':672 'freetext.fontcolor':676 'fromselect':484 'fulltext':499 'func':167,409,592,879,895,978,1165,1174 'generat':33,825 'go':337,373 'graphic':1339 'guard':271,413,1021 'handl':143,1240 'happen':1231 'height':540,630,663,694,817,836,855,1091,1119 'high':238 'highlight':24,546,589,600,607,614,730,731,735 'highlight.color':610 'histori':334,367 'hit':943 'icon':750 'ident':1159,1248 'ignor':1055 'ignoressafearea':927 'implement':458 'import':115,156,158,553,869,871 'increas':1073 'increment':468 'index':423,429 'indic':1204 'individu':962 'info.plist':112 'init':1004,1188 'initi':1012,1201 'ink':756,757 'inlin':753 'instanc':21 'integr':90,93,860 'interact':472,937,965 'intern':706 'io':56,119,491,953 'ipado':121 'islock':1242 'larg':456,1265 'large-docu':1264 'left':1070,1099,1225 'let':163,184,253,258,263,272,304,310,343,381,414,417,422,440,480,498,503,511,524,529,542,550,565,599,619,652,683,808,829,842,876,884,911,919,986,1015,1022,1082,1100,1105,1110 'line':767,768,770 'link':680,684,697,705,708,761,762,803,1259 'link.destination':709 'link.url':700 'load':66,69,239,242,932 'loading-docu':68 'mac':123 'maco':126 'main':1234,1262 'makeuiview':880 'manipul':4,43,291 'markup':733,739,744 'match':463,476,1215 'mediabox':839,858,1104 'merg':1287 'mistak':95,98,997 'mode':196,197 'modifi':19,1123 'mutat':1230 'name':404 'nativ':1042 'navig':31,39,72,75,150,326,332,353,363,368 'need':1281 'next':475,481 'nil':355,357,359,361,372,609,635,668,699 'note':25,616,620,641,647,749 'note.color':642 'note.contents':636 'note.icontype':644 'notif':411,412,1253 'notificationcenter.default.addobserver':399 'nsobject':976 'objc':408 'object':406 'observ':395,1254 'ofsiz':674 'one':200 'opposit':1075 'option':1190 'origin':1065,1096,1222 'outlin':1290 'outputurl':295,298 'overlay':952,987,993,1289 'overlayprovid':975,995 'overlayviewfor':982 'overrid':166 'ownerpass':301 'ownerpasswordopt':300 'page':32,71,74,149,201,206,212,290,307,325,341,344,346,351,380,384,385,396,415,426,428,510,525,595,605,707,711,765,801,841,940,951,963,983,1062,1203,1256 'page-navig':73 'page.addannotation':613,646,678,704,1140,1144 'page.annotations':721 'page.bounds':1102 'page.removeannotation':722 'page.selection':531 'page.thumbnail':831 'pagebound':1101 'pagebounds.height':1107 'pagechang':403,410 'pagecount':1207 'pagelabel.text':427 'pagetext':504 'password':267,286,1237 'password-protect':266,1236 'path':760 'pattern':947,1284 'pd':36 'pdf':5,15,44,141,190,933,1038,1056,1061,1094,1219,1332,1342 'pdfannot':50,580,601,621,654,685,1312 'pdfdata':262 'pdfdestin':383,710 'pdfdocument':20,48,192,241,255,260,265,274,878,921,1003,1005,1008,1017,1024,1149,1153,1187,1304 'pdfdocumentdeleg':451 'pdfi':1106,1116 'pdfkit':1,8,37,107,116,157,872,1129,1229,1295 'pdfkitview':874,924 'pdfpage':49,314,588,596,984,1308 'pdfpageoverlayviewprovid':955,977,1324 'pdfs':62,65,133,269,1239 'pdfselect':30,52,442,598,1316 'pdfthumbnailview':795,796,810,1320 'pdfthumbnailview.pdfview':1258 'pdfview':12,47,134,164,165,176,327,407,806,812,862,883,885,886,894,897,898,979,981,1034,1167,1168,1176,1177,1263,1300 'pdfview.autoresizingmask':172 'pdfview.autoscales':177,227,887,1049,1196 'pdfview.cangoback':370 'pdfview.cangotonextpage':366 'pdfview.currentpage':416 'pdfview.displaydirection':181 'pdfview.displaymode':179,889 'pdfview.displayspagebreaks':233 'pdfview.document':191,345,419,891,902,904,1046,1051,1171,1181,1183 'pdfview.frame':170 'pdfview.go':349,392,572 'pdfview.goback':371 'pdfview.gotofirstpage':358 'pdfview.gotolastpage':360 'pdfview.gotonextpage':354 'pdfview.gotopreviouspage':356 'pdfview.highlightedselections':562 'pdfview.interpolationquality':237 'pdfview.isfindinteractionenabled':493 'pdfview.maxscalefactor':231 'pdfview.minscalefactor':229 'pdfview.pageoverlayviewprovider':994 'pdfview.pageshadowsenabled':235 'pdfview.scalefactorforsizetofit':230 'pdfview.setcurrentselection':568 'pdfviewcontrol':161 'pdfviewpagechang':405,1252 'place':956 'platform':117 'point':377 'print':1288 'programmat':827 'prompt':287 'proper':1200 'protect':268,1238 'provid':328 'purpos':729 'receiv':461 'rectangl':775 'refer':104,105,726,1156,1282 'references/pdfkit-patterns.md':949,950,1293,1294 'region':520 'region-bas':519 'remov':715 'render':140,969,1039 'replac':1163 'requir':108 'resolut':1043 'result':441,548,551,559,563 'results.first':567 'return':278,421,893,992,1028 'review':99,102,1185 'review-checklist':101 'rubber':783 'safe':1135 'sampl':188 'save':288,1273 'scale':223 'scroll':145,222 'scrollabl':209 'search':40,77,82,434,438,444,449,454,469,547,1267 'see':948 'select':79,84,147,436,479,530,544,557,597 'selection.bounds':603 'selection.color':560 'selector':401,402 'self':400 'sequenti':352 'set':1198 'setup':59,60,106 'shape':776,780 'show':14,285,797 'side':213,215 'signatur':26 'singl':509 'singlepag':199 'singlepagecontinu':180,205,890 'skill' 'skill-pdfkit' 'sosumi.ai':1298,1302,1306,1310,1314,1318,1322,1326,1335,1344 'sosumi.ai/documentation/pdfkit)':1297 'sosumi.ai/documentation/pdfkit/adding-custom-graphics-to-a-pdf)':1343 'sosumi.ai/documentation/pdfkit/adding-widgets-to-a-pdf-document)':1334 'sosumi.ai/documentation/pdfkit/pdfannotation)':1313 'sosumi.ai/documentation/pdfkit/pdfdocument)':1305 'sosumi.ai/documentation/pdfkit/pdfpage)':1309 'sosumi.ai/documentation/pdfkit/pdfpageoverlayviewprovider)':1325 'sosumi.ai/documentation/pdfkit/pdfselection)':1317 'sosumi.ai/documentation/pdfkit/pdfthumbnailview)':1321 'sosumi.ai/documentation/pdfkit/pdfview)':1301 'source-dpearson2699' 'space':1221 'specif':340,376 'squar':773,774 'stack':207 'stamp':781,782,784 'standard':971 'state':364 'sticki':640,748 'straight':769 'strikeout':741,742 'strikethrough':745 'string':508,545,702 'strip':799 'struct':873,908 'subclass':138 'subtyp':725,727 'subview':991 'super.viewdidload':169 'swift':54,114,155,226,252,270,292,336,398,439,473,497,549,591,618,651,682,717,807,828,868,907,973,1013,1044,1078,1136,1160 'swiftui':89,92,859,867,870,1245 'swiftui-integr':91 'synchron':437 'system':488,1058 'systemimag':934 'systemyellow':643 'target':53 'targetpag':712 'term':445,483 'text':28,76,81,146,433,495,543,615,633,649,732,738,743,746,747,754,791 'text-search-and-select':80 'thread':1128,1134,1235 'thread-saf':1133 'thumbnail':34,87,88,794,802,826,830,843,850 'thumbnailview':809,824 'thumbnailview.layoutmode':819 'thumbnailview.pdfview':811 'thumbnailview.thumbnailsize':813 'thumbnailview.translatesautoresizingmaskintoconstraints':821 'time':204 'top':960 'topic-accessibility' 'topic-agent-skills' 'topic-ai-coding' 'topic-apple' 'topic-claude-code' 'topic-codex-skills' 'topic-cursor-skills' 'topic-ios' 'topic-ios-development' 'topic-liquid-glass' 'topic-localization' 'topic-mapkit' 'track':335,941,1257 'true':178,228,234,236,494,571,888,1050,1197 'tvos':128 'two':211,218 'two-up':217 'twoup':210 'twoupcontinu':216 'type':1157 'uicolor.yellow.withalphacomponent':611 'uifont.systemfont':673 'uikit':159,957,1077,1080 'uiview':137,985,988 'uiviewcontrol':162 'uiviewrepresent':865,875,1152 'unabl':930 'underlin':736,737,740 'unlock':1243 'unwrap':1002,1195 'updateuiview':896,1166,1175,1251 'upward':1074 'url':185,193,194,245,256,275,276,701,763,912,913,922,923,1006,1018,1019,1025,1026 'usag':906 'use':7,9,450,1158,1189,1218,1247,1268,1275 'userpass':303 'userpassword':284 'userpasswordopt':302 'var':914 'vertic':182,208,820 'view':910,917,958,980 'view.addsubview':175,823 'view.bounds':171 'viewdidload':168 'visiono':130 'watermark':1286 'widget':787,788,1329 'width':538,628,661,692,815,834,853,1089,1117 'withextens':189 'withopt':299,446,486,554,1278 'without':1035 'withpageat':323 'withpassword':283,1244 'withproperti':583,608,634,667,698 'wrap':861 'wrapper':938,1246 'write':1276 'wrong':1014,1045,1079,1137,1161 'x':388,534,624,657,688,1085,1113 'y':390,536,626,659,690,1072,1087,1115,1226 'yellow':561,734 'zero':714 'zoom':144","prices":[{"id":"b3fe09aa-3dcf-460a-8fdb-f7aeab05707b","listingId":"180fee10-ced0-4053-8266-5a2d49960389","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"dpearson2699","category":"swift-ios-skills","install_from":"skills.sh"},"createdAt":"2026-04-18T22:01:09.643Z"}],"sources":[{"listingId":"180fee10-ced0-4053-8266-5a2d49960389","source":"github","sourceId":"dpearson2699/swift-ios-skills/pdfkit","sourceUrl":"https://github.com/dpearson2699/swift-ios-skills/tree/main/skills/pdfkit","isPrimary":false,"firstSeenAt":"2026-04-18T22:01:09.643Z","lastSeenAt":"2026-04-22T00:53:44.001Z"}],"details":{"listingId":"180fee10-ced0-4053-8266-5a2d49960389","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"dpearson2699","slug":"pdfkit","github":{"repo":"dpearson2699/swift-ios-skills","stars":468,"topics":["accessibility","agent-skills","ai-coding","apple","claude-code","codex-skills","cursor-skills","ios","ios-development","liquid-glass","localization","mapkit","networking","storekit","swift","swift-concurrency","swiftdata","swiftui","widgetkit","xcode"],"license":"other","html_url":"https://github.com/dpearson2699/swift-ios-skills","pushed_at":"2026-04-21T19:26:16Z","description":"Agent Skills for iOS 26+, Swift 6.3, SwiftUI, and modern Apple frameworks","skill_md_sha":"a223daae5fb44d78d2d39b2b2c5715bd989b4792","skill_md_path":"skills/pdfkit/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/dpearson2699/swift-ios-skills/tree/main/skills/pdfkit"},"layout":"multi","source":"github","category":"swift-ios-skills","frontmatter":{"name":"pdfkit","description":"Display and manipulate PDF documents using PDFKit. Use when embedding PDFView to show PDF files, creating or modifying PDFDocument instances, adding annotations (highlights, notes, signatures), extracting text with PDFSelection, navigating pages, generating thumbnails, filling PDF forms, or wrapping PDFView in SwiftUI."},"skills_sh_url":"https://skills.sh/dpearson2699/swift-ios-skills/pdfkit"},"updatedAt":"2026-04-22T00:53:44.001Z"}}