---
title: "Migrating from Apple PDFKit"
canonical_url: "https://www.nutrient.io/guides/ios/migration-guides/migrating-from-apple-pdfkit/"
md_url: "https://www.nutrient.io/guides/ios/migration-guides/migrating-from-apple-pdfkit.md"
last_updated: "2026-05-23T00:08:18.115Z"
description: "Comprehensive upgrade guide for Nutrient iOS SDK covering version migrations, breaking changes, and new features."
---

Apple’s PDFKit provides a great starting point for integrating PDF support into your iOS app. It’s a system library, so it’s easy to integrate.

PSPDFKit, on the other hand, is a cross-platform PDF framework with more advanced features and fine-grained control over various aspects of PDF handling. It also includes a lot of customization options:

- Advanced and native UI and UX, with support for most PDF features

- Support for all annotations defined in the PDF specification

- Importing and exporting annotations in JSON and XFDF formats

- Accessing files embedded in documents

- Adding watermarks to documents

- Programmatic form filling

- Indexed full-text search (with near-instant search results)

- Loading of documents from custom sources with on-the-fly decryption

- Advanced, customizable rendering, including CMYK color space support

- Custom bookmark implementation (bookmarks are not part of the PDF spec)

- Available on multiple platforms with excellent interoperability

- Constantly improving with new features

- First-class support directly from our engineers

To simplify migrating a codebase from PDFKit to PSPDFKit as much as possible, we provide a wrapper called [PDFXKit](https://github.com/PSPDFKit/PDFXKit). It’s a drop-in replacement with little or no changes required, and it allows you to program against the PDFKit API while using PSPDFKit under the hood. See the [Easy Transition with PDFXKit](#easy-transition-with-pdfxkit) section below for more information.

## Introduction

The PSPDFKit API can be overwhelming at first, especially when coming from Apple PDFKit. But once you understand the basic concepts, it’s straightforward. We traded a bit of simplicity for flexibility and performance, and we achieve this by using a couple of techniques and patterns.

For example, the responsibility for providing, parsing, and managing various PDF objects and concepts is split into individual classes. These are called `...Provider`, `...Parser`, and `...Manager`. We expose the classes publicly to give you hooks for customization, advanced control, and performance optimization.

## Overview

The only UI classes provided by Apple’s PDFKit are `PDFView` and `PDFThumbnailView`. All remaining classes in Apple’s PDFKit are what Apple calls utility classes. Let’s take a look at these and see how they relate to PSPDFKit.

The following table shows an overview of Apple’s PDFKit classes that have a corresponding class in PSPDFKit:

| Apple’s PDFKit         | Nutrient                |
| ---------------------- | ----------------------- |
| [`PDFView`](https://developer.apple.com/documentation/pdfkit/pdfview)          | [`PDFViewController`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/pdfviewcontroller) |
| [`PDFThumbnailView`](https://developer.apple.com/documentation/pdfkit/pdfthumbnailview) | [`ScrubberBar`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/scrubberbar)       |
| [`PDFDocument`](https://developer.apple.com/documentation/pdfkit/pdfdocument)      | [`Document`](https://www.nutrient.io/api/ios/documentation/pspdfkit/document)          |
| [`PDFAnnotation`](https://developer.apple.com/documentation/pdfkit/pdfannotation)    | [`Annotation`](https://www.nutrient.io/api/ios/documentation/pspdfkit/annotation)        |
| [`PDFOutline`](https://developer.apple.com/documentation/pdfkit/pdfoutline)       | [`OutlineElement`](https://www.nutrient.io/api/ios/documentation/pspdfkit/outlineelement)    |

The [`PDFPage`](https://developer.apple.com/documentation/pdfkit/pdfpage) class doesn’t have a corresponding class in PSPDFKit; the concept of a page is supported mainly via page indexes, as described in more detail in the [Page Handling](#page-handling) section.

The [`PDFSelection`](https://developer.apple.com/documentation/pdfkit/pdfselection) class doesn’t have a corresponding class in PSPDFKit. While `PDFSelection` is generic in Apple’s PDFKit, covering multiple use cases, PSPDFKit offers more dedicated objects for each use case. Text selected by a user is a UI concept. For more information, see the [Text Handling](#text-handling) section.

## Document Handling

The [`PDFDocument`](https://developer.apple.com/documentation/pdfkit/pdfdocument) class in Apple PDFKit represents a single PDF document either stored on disk as a file or loaded via a `Data` object. This class corresponds to [`Document`](https://www.nutrient.io/api/ios/documentation/pspdfkit/document) in PSPDFKit.

A [`Document`](https://www.nutrient.io/api/ios/documentation/pspdfkit/document) consists of one or more [`PDFDocumentProvider`](https://www.nutrient.io/api/ios/documentation/pspdfkit/pdfdocumentprovider)s. You can think of one provider as corresponding to a single file on disk. This allows you to treat multiple PDF files as a single document in cases where you need to. Many customers use this feature to split large documents up into individual files — for example, to download each part individually on demand.

## Page Handling

As noted above, PSPDFKit doesn’t have a corresponding class for [`PDFPage`](https://developer.apple.com/documentation/pdfkit/pdfpage). Anything related to a page is accessed via the document or a related object by passing a page index. For example, you’d use [`Document`](https://www.nutrient.io/api/ios/documentation/pspdfkit/document)’s [`annotationsForPage(at:type:)`](https://www.nutrient.io/api/ios/documentation/pspdfkit/document/annotationsforpage(at:type:)) to get annotations for a specific page. Page indexed access allows PSPDFKit to better optimize for performance.

The main object for manipulating pages of a document is [`PDFDocumentEditor`](https://www.nutrient.io/api/ios/documentation/pspdfkit/pdfdocumenteditor) and its related classes ([see the Document Editor announcement blog post](https://www.nutrient.io/blog/the-document-editor/)). It allows you to:

- Add pages

- Remove pages

- Duplicate pages

- Rotate pages

- Extract pages (saving as a new PDF document)

Consult the [document editing](https://www.nutrient.io/guides/ios/features/document-editor.md) guide, particularly the section on [programmatic access](https://www.nutrient.io/guides/ios/features/document-editor.md#programmatic-access).

## Text Handling

Other than selecting text at the UI level, extracting text and inspecting blocks of text are probably the two main use cases of [`PDFSelection`](https://developer.apple.com/documentation/pdfkit/pdfselection) in Apple PDFKit.

In PSPDFKit, both of these use cases are covered by [`TextParser`](https://www.nutrient.io/api/ios/documentation/pspdfkit/textparser), which you can access via the [`textParserForPage(at:)`](https://www.nutrient.io/api/ios/documentation/pspdfkit/document/textparserforpage(at:)) method of [`Document`](https://www.nutrient.io/api/ios/documentation/pspdfkit/document). It offers a simple API to get text, glyphs ([`Glyph`](https://www.nutrient.io/api/ios/documentation/pspdfkit/glyph)), words ([`Word`](https://www.nutrient.io/api/ios/documentation/pspdfkit/word)), text blocks ([`TextBlock`](https://www.nutrient.io/api/ios/documentation/pspdfkit/textblock)), and even images ([`ImageInfo`](https://www.nutrient.io/api/ios/documentation/pspdfkit/imageinfo)).

In a PDF, text usually corresponds to glyphs positioned at an absolute location on a specific page. PSPDFKit uses advanced heuristics to group these glyphs into meaningful words and text blocks.

## Outline

The `PDFOutline` class encapsulates the outline concept of a PDF document. PSPDFKit has a corresponding class named [`OutlineElement`](https://www.nutrient.io/api/ios/documentation/pspdfkit/outlineelement), which works similarly to `PDFOutline`. You can access the outline via the [`outline`](https://www.nutrient.io/api/ios/documentation/pspdfkit/document/outline) property on [`Document`](https://www.nutrient.io/api/ios/documentation/pspdfkit/document):

### SWIFT

```swift

let document = /* Create a PSPDFDocument  */
let rootOutlineElement = document.outline

```

### OBJECTIVE-C

```objc

PSPDFDocument *document = /* Create a PSPDFDocument  */;
PSPDFOutlineElement* rootOutlineElement = document.outline;

```

With the root outline element, you can walk the outline tree, get information, and perform operations on the outline elements, similar to how you would with [`PDFOutline`](https://developer.apple.com/documentation/pdfkit/pdfoutline). For more information, consult the [API Reference](https://www.nutrient.io/api/ios/).

## Annotations

Apple PDFKit provides a single [`PDFAnnotation`](https://developer.apple.com/documentation/pdfkit/pdfannotation) class, together with a small [`PDFBorder`](https://developer.apple.com/documentation/pdfkit/pdfborder) utility class representing annotations and their borders. PSPDFKit supports all annotations as defined by the PDF specification with a rich and flexible API. We have [an extensive guide covering all aspects of annotations](https://www.nutrient.io/guides/ios/annotations/introduction-to-annotations.md).

## Search

PSPDFKit offers two search options:

- Regular search, which is equivalent to Apple PDFKit and easy to use

- Indexed full-text search, which is blazing fast but requires more setup

To perform a regular search for a document, create an instance of [`TextSearch`](https://www.nutrient.io/api/ios/documentation/pspdfkit/textsearch), passing in the loaded [`Document`](https://www.nutrient.io/api/ios/documentation/pspdfkit/document) via its initializer. Searching can be triggered via calling [`search(for:)`](https://www.nutrient.io/api/ios/documentation/pspdfkit/textsearch/search(for:)), which will start a search in a background queue. Implement [`TextSearchDelegate`](https://www.nutrient.io/api/ios/documentation/pspdfkit/textsearchdelegate) on the receiving object and set the text search object’s delegate to your object to be notified of search result updates.

To learn more about our blazingly fast indexed full-text search, refer to the [indexed full-text search](https://www.nutrient.io/guides/ios/features/indexed-full-text-search.md) guide.

## Rendering

Apple PDFKit lets you render a `PDFPage` into a specific context using the `drawWithBox:toContext:` method. Similarly, the easiest way to render a page with `PSPDFKit` is to use one of the following [`Document`](https://www.nutrient.io/api/ios/documentation/pspdfkit/document) methods:

### SWIFT

```swift

// `Document`
func imageForPage(at pageIndex: PageIndex, size: CGSize, clippedTo clipRect: CGRect, annotations: [Annotation]?, options: RenderOptions?) throws -> UIImage
func renderPage(at pageIndex: PageIndex, context: CGContext, size: CGSize, clippedTo clipRect: CGRect, annotations: [Annotation]?, options: RenderOptions?) throws

```

### OBJECTIVE-C

```objc

// `PSPDFDocument`

- (nullable UIImage *)imageForPageAtIndex:(PSPDFPageIndex)pageIndex size:(CGSize)size clippedToRect:(CGRect)clipRect annotations:(nullable NSArray<PSPDFAnnotation *> *)annotations options:(nullable PSPDFRenderOptions *)options error:(NSError *_Nullable *_Nullable)error;

- (BOOL)renderPageAtIndex:(PSPDFPageIndex)pageIndex context:(nonnull CGContextRef)context size:(CGSize)size clippedToRect:(CGRect)clipRect annotations:(nullable NSArray<PSPDFAnnotation *> *)annotations options:(nullable PSPDFRenderOptions *)options error:(NSError *_Nullable *_Nullable)error;

```

Beyond this basic rendering support, PSPDFKit offers an advanced, asynchronous rendering pipeline that gives you control over various aspects of the rendering result and performance. You first create a [`RenderRequest`](https://www.nutrient.io/api/ios/documentation/pspdfkit/renderrequest), which specifies what and how to render the page. You use that render request to create a [`RenderTask`](https://www.nutrient.io/api/ios/documentation/pspdfkit/rendertask), set yourself as a delegate on that, and schedule it in a [`RenderQueue`](https://www.nutrient.io/api/ios/documentation/pspdfkit/renderqueue). Once finished, the render task will notify the delegate and pass it the resulting image. See the [rendering PDF pages](https://www.nutrient.io/guides/ios/getting-started/rendering-pdf-pages.md) guide for more details.

For more information on advanced rendering, consult the [API Reference](https://www.nutrient.io/api/ios/) for these classes, along with our PSPDFKit Catalog example project. See the [Example Projects](https://www.nutrient.io/guides/ios/getting-started/example-projects.md) guide for more details.

## Basic User Interface

As of iOS 11, PDFKit provides two UI classes for displaying and browsing PDF files: [`PDFView`](https://developer.apple.com/documentation/pdfkit/pdfview) and [`PDFThumbnailView`](https://developer.apple.com/documentation/pdfkit/pdfthumbnailview).

`PDFView` is the main UI class that allows you to display a PDF document using different display modes and options to tweak the appearance. The corresponding class in PSPDFKit is the [`PDFViewController`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/pdfviewcontroller).

[`PDFThumbnailView`](https://developer.apple.com/documentation/pdfkit/pdfthumbnailview) is an accessory control for a `PDFView` showing a strip of thumbnails for each page of the currently displayed PDF document. The corresponding class in PSPDFKit is the [`ScrubberBar`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/scrubberbar).

Unlike [`PDFView`](https://developer.apple.com/documentation/pdfkit/pdfview), the [`PDFViewController`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/pdfviewcontroller) is meant to be a drop-in solution with very little code or UI required from your side. All you have to do is create a [`PDFViewController`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/pdfviewcontroller) and present it as is. Everything else is handled for you automatically by default — including displaying the [`ScrubberBar`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/scrubberbar).

The following code snippet demonstrates how to display a PDF using [`PDFViewController`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/pdfviewcontroller) and a thumbnail bar matching the one from PDFKit:

### SWIFT

```swift

import PSPDFKit

// Load the document.
let documentURL = Bundle.main.url(forResource: "Document", withExtension: "pdf")!
let document = Document(url: documentURL)

// Create a configuration object and tweak the thumbnail bar, which will use
// the appropriate view — in this case, the `ScrubberBar`.
let configuration = PDFConfiguration {
    $0.thumbnailBarMode =.scrubberBar
    // Add your configuration options here.
}

// Put the PDF view controller inside a navigation controller to
// give it a navigation bar for various PDF-related controls.
let pdfViewController = PDFViewController(document: document, configuration: configuration)
let navigationController = UINavigationController(rootViewController: pdfViewController)

present(navigationController, animated: true)

```

### OBJECTIVE-C

```objc

#import <PSPDFKit/PSPDFKit.h>

// Load the document.
NSURL *documentURL = [NSBundle.mainBundle URLForResource:@"Document" withExtension:@"pdf"];
PSPDFDocument *document = [[PSPDFDocument alloc] initWithURL:documentURL];

// Create a configuration object and tweak the thumbnail bar, which will use
// the appropriate view — in this case, the `PSPDFScrubberBar`.
PSPDFConfiguration *configuration = [PSPDFConfiguration configurationWithBuilder:^(PSPDFConfigurationBuilder *builder) {
    builder.thumbnailBarMode = PSPDFThumbnailBarModeScrubberBar;
    // Add your configuration options here.
}];

// Put the PDF view controller inside a navigation controller to
// give it a navigation bar for various PDF-related controls.
PSPDFViewController *pdfViewController = [[PSPDFViewController alloc] initWithDocument:document configuration:configuration];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:pdfViewController];

[self presentViewController:navigationController animated:YES completion:NULL];

```

The result should look something like this:![PDF page coordinates](@/assets/guides/ios/migration-guides/migrating-from-apple-pdfkit/Basic-UI.png)

## Advanced User Interface

Apart from basic support for displaying and browsing PDFs with the two PDFKit classes above, everything else needs to be implemented from scratch with PDFKit. PSPDFKit, on the other hand, provides everything you need to handle PDFs in your app, ready to be used out of the box.

When presented within a navigation controller, the `PDFViewController` puts a couple of buttons into the navigation bar by default, giving you access to the following features:

- **Adding, deleting, and editing annotations** — By default, the first button in the navigation bar is the annotations button, which provides access to the annotation toolbar. The support of annotations is a big part of PSPDFKit; consult our [PDF annotations](https://www.nutrient.io/guides/ios/annotations/introduction-to-annotations.md) page and [introduction to annotations](https://www.nutrient.io/guides/ios/annotations/introduction-to-annotations.md) guide for an in-depth look at these.

- **Searching and navigating search results** — Next to the annotations button, you’ll find the magnifying glass button, which presents the [`SearchViewController`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/searchviewcontroller).

- **Displaying and managing the document outline, its annotations, bookmarks, and files** — Next up is the bookmark button, which gives you access to [`OutlineViewController`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/outlineviewcontroller), [`BookmarkViewController`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/bookmarkviewcontroller), [`AnnotationTableViewController`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/annotationtableviewcontroller), and [`EmbeddedFilesViewController`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/embeddedfilesviewcontroller). See our [core viewer](https://www.nutrient.io/guides/ios/viewer.md) page for a visual walkthrough of these features.

- **Inserting, deleting, and reordering pages** — The last button in the navigation bar gives you access to the [`ThumbnailViewController`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/thumbnailviewcontroller), from which you get to the [`PDFDocumentEditorViewController`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/pdfdocumenteditorviewcontroller), which allows you to manage the pages of a document. See our [PDF document editor](https://www.nutrient.io/guides/ios/features/document-processing.md) page and the corresponding [document editing](https://www.nutrient.io/guides/ios/features/document-editor.md) guide for more information.

PSPDFKit offers more UI components not directly accessible via the [`PDFViewController`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/pdfviewcontroller), including the [`PDFDocumentPickerController`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/pdfdocumentpickercontroller) and the [`PDFTabbedViewController`](https://www.nutrient.io/api/ios/documentation/pspdfkitui/pdftabbedviewcontroller). All of these components are designed to be easy to integrate and customize so as to perfectly blend into your app. To learn more, look at our [customizing the interface](https://www.nutrient.io/guides/ios/customizing-the-interface/appearance-mode-manager.md) section of the guides, as well as our extensive [documentation](https://www.nutrient.io/guides/ios.md) and [API Reference](https://www.nutrient.io/api/ios/documentation/overview).

## Easy Transition with PDFXKit

If your app is already using PDFKit, migrating the full codebase to PSPDFKit can be a major undertaking and a dealbreaker for many developers. In this case, we encourage you to give [PDFXKit](https://github.com/PSPDFKit/PDFXKit) a try.

[PDFXKit](https://www.nutrient.io/blog/introducing-pdfxkit/) is a drop-in replacement that gives you the same APIs as PDFKit while using PSPDFKit under the hood, with only a few tweaks required. PDFXKit gives you full access to the underlying PSPDFKit, allowing you take advantage of all PSPDFKit features, components, and tools if and when you need them.

PDFXKit is open source. Visit the [project page](https://github.com/PSPDFKit/PDFXKit) on GitHub for more information.

## Conclusion

If you have experience with Apple PDFKit, by now you should have a rough idea of how to translate that to PSPDFKit. If you have an existing codebase using PDFKit, PDFXKit makes the transition to PSPDFKit a breeze.

While PDFKit is a great starting point for adding basic PDF support to your app, PSPDFKit goes much further, offering you a cross-platform drop-in solution with many UI components, advanced PDF features, and first-class support directly from the developers.

Consult our [website](https://pspdfkit.com/), our [guides](https://www.nutrient.io/guides/ios.md), and our [API Reference](https://www.nutrient.io/api/ios/documentation/overview) for additional information about various parts of PSPDFKit.
---

## Related pages

- [Migrate to electronic signatures](/guides/ios/migration-guides/migrating-to-electronic-signatures.md)
- [14 2 Migration Guide](/guides/ios/migration-guides/14-2-migration-guide.md)
- [Migrating To Advanced Digital Signatures Api](/guides/ios/migration-guides/migrating-to-advanced-digital-signatures-api.md)
- [14 9 Migration Guide](/guides/ios/migration-guides/14-9-migration-guide.md)
- [Pspdfkit 10 4 Migration Guide](/guides/ios/migration-guides/pspdfkit-10-4-migration-guide.md)
- [Pspdfkit 10 Migration Guide](/guides/ios/migration-guides/pspdfkit-10-migration-guide.md)
- [Pspdfkit 10 3 Migration Guide](/guides/ios/migration-guides/pspdfkit-10-3-migration-guide.md)
- [Pspdfkit 11 3 Migration Guide](/guides/ios/migration-guides/pspdfkit-11-3-migration-guide.md)
- [Pspdfkit 12 2 Migration Guide](/guides/ios/migration-guides/pspdfkit-12-2-migration-guide.md)
- [Pspdfkit 12 3 Migration Guide](/guides/ios/migration-guides/pspdfkit-12-3-migration-guide.md)
- [Pspdfkit 13 Migration Guide](/guides/ios/migration-guides/pspdfkit-13-migration-guide.md)
- [Pspdfkit 11 5 Migration Guide](/guides/ios/migration-guides/pspdfkit-11-5-migration-guide.md)
- [Pspdfkit 13 3 Migration Guide](/guides/ios/migration-guides/pspdfkit-13-3-migration-guide.md)
- [Pspdfkit 11 4 Migration Guide](/guides/ios/migration-guides/pspdfkit-11-4-migration-guide.md)
- [Pspdfkit 4 Migration Guide](/guides/ios/migration-guides/pspdfkit-4-migration-guide.md)
- [Pspdfkit 3 Migration Guide](/guides/ios/migration-guides/pspdfkit-3-migration-guide.md)
- [Pspdfkit 12 Migration Guide](/guides/ios/migration-guides/pspdfkit-12-migration-guide.md)
- [Pspdfkit 5 Migration Guide](/guides/ios/migration-guides/pspdfkit-5-migration-guide.md)
- [Pspdfkit 6 5 Migration Guide](/guides/ios/migration-guides/pspdfkit-6-5-migration-guide.md)
- [Pspdfkit 6 Migration Guide](/guides/ios/migration-guides/pspdfkit-6-migration-guide.md)
- [Pspdfkit 9 2 Migration Guide](/guides/ios/migration-guides/pspdfkit-9-2-migration-guide.md)
- [Pspdfkit 9 4 Migration Guide](/guides/ios/migration-guides/pspdfkit-9-4-migration-guide.md)
- [Migrate to PSPDFKit 7 with ease](/guides/ios/migration-guides/pspdfkit-7-migration-guide.md)
- [Pspdfkit 9 3 Migration Guide](/guides/ios/migration-guides/pspdfkit-9-3-migration-guide.md)
- [Pspdfkit 7 6 Migration Guide](/guides/ios/migration-guides/pspdfkit-7-6-migration-guide.md)
- [Pspdfkit 9 5 Migration Guide](/guides/ios/migration-guides/pspdfkit-9-5-migration-guide.md)
- [Pspdfkit 9 Migration Guide](/guides/ios/migration-guides/pspdfkit-9-migration-guide.md)
- [Upgrading](/guides/ios/getting-started/upgrading.md)
- [PSPDFKit 8 migration guide for iOS developers](/guides/ios/migration-guides/pspdfkit-8-migration-guide.md)

