PDF Toolbox
PDF Toolbox is built on Apple's native PDFKit and CoreGraphics frameworks. This page describes how each tool processes PDFs and how the output relates to published PDF specifications. Requires iOS/iPadOS 18.1+ or macOS 15.1+.
The following ISO standards define the PDF format. PDF Toolbox's output is described in relation to these specifications, though the app has not been formally certified or audited by any standards body.
PDF 1.7 covers core PDF structure, content streams, annotations, encryption, and metadata. The foundation standard for all PDF operations.
PDF 2.0 adds extended page boxes, annotation types, and encryption algorithms. Used for forward-compatibility verification.
PDF/A-1b is the long-term archival format requiring embedded fonts, ICC colour profiles, XMP metadata, and no interactive elements.
How each tool processes PDFs and what is preserved in the output. This is a self-assessment by the developer and has not been independently verified.
| Tool | Preservation | Approach | Key Detail |
|---|---|---|---|
| Merge PDF | Full | PDFDocument insert | Non-destructive page copy; all annotations preserved |
| Split PDF | Full | PDFDocument insert | Non-destructive; cross-page destinations may orphan |
| Compress (Smart) | Full | Selective image re-encode + byte patch | Only embedded images are recompressed; text, vectors, and structure preserved |
| Repair PDF | Visual | Diagnose + CGContext re-render | Rebuilds damaged structure; interactive elements become static |
| Redact PDF | Full | CGContext raster of affected pages | Redacted pages rasterised so hidden text is forensically destroyed; clean pages untouched |
| PDF to Images | N/A | PDFPage.draw to raster | Output is raster images, not PDF |
| Images to PDF | N/A | CGContext new PDF | Creates new PDF from raster images |
| Rotate / Delete / Extract / Reorder | Full | PDFDocument API | Non-destructive page tree manipulation |
| Resize PDF | Visual only | CGContext CTM transform | Links, forms, bookmarks lost in re-draw |
| Watermark | Full | Annotation + flatten | Stamp annotation with appearance stream |
| Page Numbers | Full | Annotation + flatten | CoreText rendered into annotation appearance |
| Sign PDF | Full | Annotation + flatten | Visual e-signature (stamp), not PKCS#7 digital signature |
| Unlock PDF | Full | PDFDocument write | Strips /Encrypt via write options; preserves bookmarks, forms, and named destinations |
| Protect PDF | Full | PDFDocument write+options | AES-128/256 encryption |
| Edit Metadata | Full | PDFDocument attributes | Standard /Info dict + XMP sync |
| Remove Metadata | Full | PDFMetadataSanitiser byte patch | Strips /Info and XMP without PDFKit re-injecting /Producer; fast path for flat PDFs |
| OCR (Searchable PDF) | Visual only | RecognizeTextRequest + 3 Tr | On-device Vision OCR; optional Scanned Document preprocessing and scan resolution; links lost in re-draw |
| Flatten (Standard) | Visual only | CGContext vector flatten | Link actions lost; text stays selectable |
| Flatten (Rasterize) | By design | CGContext bitmap | Intentionally converts all content to images |
| Flatten (Rasterize + OCR) | By design | CGContext bitmap + RecognizeTextRequest | Raster DPI follows scan resolution when OCR runs; adds searchable text layer |
| Convert to PDF/A | Best effort | CGContext + XMP + ICC | Font substitution for non-installed fonts |
| Camera to PDF | N/A | CGContext new PDF | Creates new PDF from camera images |
| Viewer Redact | By design | RedactionService CGContext raster | Marks applied on save; affected pages rasterised so hidden text is destroyed; marks never written as annotations |
| Text Search | Full | PDFDocument.findString (read-only) | CMap-based text extraction; view-only highlighting |
| Print PDF | Full | UIPrintInteractionController | Sends PDF directly to iOS print subsystem; no re-rendering |
| Share PDF | Full | UIActivityViewController | Shares original file URL; no PDF transformation |
| Highlight Annotation | Full | PDFAnnotation (.highlight) | Text markup annotation with QuadPoints per ISO 32000-2 |
| Underline Annotation | Full | PDFAnnotation (.underline) | Text markup annotation with QuadPoints per ISO 32000-2 |
| Ink Drawing | Full | PDFAnnotation (.ink) | InkList path arrays from touch points; ISO 32000-2 §12.5.6.13 |
| FreeText Annotation | Full | PDFAnnotation (.freeText) | Custom appearance stream; transparent background; ISO 32000-2 §12.5.6.6 |
| Form Filling | Full | PDFKit AcroForm engine | Native widget interaction; field values persisted per ISO 32000-2 §12.7 |
PDF Toolbox uses three distinct pipelines, each with different preservation characteristics.
Used by Merge, Split, Rotate, Delete, Extract, Reorder, Unlock, Protect, and Edit Metadata. Pages are copied as objects. Content streams, annotations, hyperlinks, form fields, bookmarks, and metadata are preserved without modification.
Used by Resize, OCR, Flatten, Redact, Repair, Compress (image mode), and PDF/A. Pages are re-rendered as vector PDF operators. Visual fidelity is preserved, but interactive elements (link actions, form fields, bookmarks) are not re-emitted.
Used by Highlight, Underline, Ink, FreeText, and Form Filling. Annotations are added as ISO 32000-2 annotation dictionaries via PDFKit's native API. Page content streams are never modified. All changes are additive overlay annotations that can be individually removed.
The built-in PDF viewer provides interactive features that read or annotate PDFs using standard ISO 32000-2 mechanisms. All operations use PDFKit's native APIs.
Read-only. PDFDocument.findString with CMap-based text extraction
| Aspect | ISO Reference | Detail |
|---|---|---|
| Text extraction | ISO 32000-2 §9.4 | PDFKit uses CMap glyph-to-Unicode mapping, WinAnsiEncoding, MacRomanEncoding, Identity-H/V, and ToUnicode CMaps |
| Search highlighting | ISO 32000-2 §12.5.6.10 | View-only overlays via PDFView.highlightedSelections; no annotation dictionaries created |
| Content preservation | ISO 32000-2 §7.8 | Entirely read-only; no content streams, annotations, or metadata modified |
Read-only. PDF structure preserved intact
| Aspect | ISO Reference | Detail |
|---|---|---|
| Print output | ISO 32000-2 §14.11 | UIPrintInteractionController sends PDF directly to the iOS print subsystem; no content stream re-rendering |
| Unsaved changes | ISO 32000-2 §7.5 | In-memory document serialised via PDFDocument.dataRepresentation() producing a valid ISO 32000 PDF byte stream |
| Share sheet | N/A | UIActivityViewController shares the original file URL; no PDF transformation occurs |
Non-destructive annotation. ISO 32000-2 annotation subtypes via PDFKit
| Annotation Type | ISO Subtype | Key Properties |
|---|---|---|
| Highlight | /Highlight (§12.5.6.10) | Text markup with QuadPoints; yellow colour with 50% opacity |
| Underline | /Underline (§12.5.6.10) | Text markup with QuadPoints; red colour with 50% opacity |
| Ink | /Ink (§12.5.6.13) | InkList path arrays from touch points; configurable colour and line width |
| FreeText | /FreeText (§12.5.6.6) | Custom appearance stream (/AP /N) with transparent background; configurable font, size, and colour |
Non-destructive. PDFKit native AcroForm engine
| Aspect | ISO Reference | Detail |
|---|---|---|
| Interactive forms | ISO 32000-2 §12.7 | PDFKit's built-in AcroForm engine handles text fields, checkboxes, radio buttons, and combo boxes |
| Value persistence | ISO 32000-2 §12.7.4 | PDFKit updates the /V (Value) entry in field dictionaries; persisted via PDFDocument.write(to:) |
| Appearance update | ISO 32000-2 §12.5.5 | PDFKit regenerates the /AP /N XObject on value change for visual consistency |
Forensic redaction on save. RedactionService CGContext raster pipeline
| Aspect | ISO Reference | Detail |
|---|---|---|
| Marking | ISO 32000-2 §12.5 | Text selections held in memory only; marks are not written as PDF annotation dictionaries |
| Apply on save | ISO 32000-1 §7.8 | Affected pages re-rendered through CGContext; underlying text and vectors in marked regions are destroyed |
| Page scope | ISO 32000-1 §7.7.3 | Only pages with marks are rasterised; unmarked pages are copied without modification |
Permission stripping and re-encryption. ISO 32000-2 §7.6
| Aspect | ISO Reference | Detail |
|---|---|---|
| Permission stripping | ISO 32000-2 §7.6 | Owner-encrypted PDFs are re-written with empty passwords to enable annotation and form editing |
| Re-encryption on save | ISO 32000-2 §7.6.3 | Original user password restored via PDFDocument.write(to:withOptions:) with standard encryption handler |
| Content preservation | ISO 32000-2 §7.8 | Only the /Encrypt dictionary is modified; all page content streams remain unchanged |
The Convert to PDF/A tool produces output that follows the ISO 19005-1:2005 (PDF/A-1b) specification. Output has been validated with the open-source veraPDF conformance checker (0 failed checks on the reference test set), though it has not been certified by an official ISO certification body.
| ISO 19005-1 Requirement | Implementation | Notes |
|---|---|---|
| XMP metadata with pdfaid:part and pdfaid:conformance | Custom XMP packet with required fields | Added during conversion |
| OutputIntent with sRGB ICC profile | sRGB IEC61966-2.1 from CGColorSpace | Embedded in output |
| PDF version header %PDF-1.4 | Post-write header patching | Required by PDF/A-1 |
| All fonts embedded | CoreGraphics auto-embeds fonts used during re-draw | Substitute fonts used if originals are unavailable; glyph appearance may differ |
| No transparency groups | CGContext re-draw flattens all transparency | Handled by re-rendering |
| No JavaScript or multimedia | CGContext re-draw strips interactive elements | Handled by re-rendering |
| No encryption | Output is never re-encrypted | Enforced |
| Post-write verification | Basic binary scan for /GTS_PDFA1 and %PDF-1.4 | Not a full conformance check |
Tools that could alter the archival characteristics of a PDF/A file are blocked at two levels.
Tools that could alter archival properties (Compress, Flatten, OCR, Watermark, Page Numbers, Protect, Remove Metadata) are hidden from the document context menu when a PDF/A file is detected.
Each standalone tool's file selection checks for PDF/A markers and rejects with a localised error message if the operation would alter the file's archival properties.
Reusable components shared across multiple tools and viewer features.
Two-pass pipeline: generates annotation appearance XObjects, then composites them into the content stream. Used by Watermark, Page Numbers, Sign, and Flatten. Follows the approach described in ISO 32000-1 §12.5.5.
Byte-level engine for Remove Metadata and post-write /Producer stripping across tools. Patches /Info and XMP in place on flat PDFs; normalises encrypted or ObjStm files before sanitising. Used by Remove Metadata, Unlock, Redact, and output paths that call setAppProducer.
Writes OCR-recognised text using the "3 Tr" invisible text rendering mode (ISO 32000-1). Text is searchable but not visible. Used by OCR and Flatten (Rasterize + OCR) with RecognizeTextRequest word boxes.
Interprets the /Rotate page dictionary entry (as described in ISO 32000-1 §7.7.3.3), handling 0, 90, 180, and 270 degree rotations during CGContext re-draw operations.
Custom PDFAnnotation subclass that overrides draw(with:in:) to render FreeText annotations without PDFKit's default opaque background. Applies CGContext y-axis flipping for correct text rendering in PDF coordinate space per ISO 32000-2 §8.3.4. Thread-safe for PDFKit's background rendering.
loadPDFForEditing strips owner-password permission restrictions per the ISO 32000-2 §7.6 permission model. Includes path traversal prevention (sanitizeFilename), symlink validation (validateOutputPath), and iOS path normalisation.
For questions about PDF Toolbox's technical details, you can reach the developer on X: