Integrating PSPDFKit

The simplest way to integrate PSPDFKit is to use CocoaPods. See Using CocoaPods for details.

Alternatively, you can manually add the dynamic framework to your project. There's no functional difference — it's simply a matter of preference. Log in to your customer portal at customers.pspdfkit.com and download the latest version of PSPDFKit. Then open the disk image and copy PSPDFKit.framework and PSPDFKitUI.framework into your project.

If you don't yet have a license, request an evaluation license here first and follow the instructions in the email.

Requirements

PSPDFKit requires the latest stable version of Xcode available at the time the release was made. This is a hard requirement, as each version of Xcode is bundled with a specific version of the iOS Base SDK, which often defines how UIKit and various other frameworks behave. See the README for version details.

Integrating the Dynamic Framework

  1. Drag PSPDFKit.framework and PSPDFKitUI.framework into the Embedded Binaries section of your target:

  1. Add a new Run Script Phase in your target’s Build Phases.

IMPORTANT: Make sure this Run Script Phase is below the Embed Frameworks build phase.
You can drag and drop build phases to rearrange them.

Paste the following line in the script text field of Run Script Phase:

1
bash "$BUILT_PRODUCTS_DIR/$FRAMEWORKS_FOLDER_PATH/PSPDFKit.framework/strip-framework.sh"

This script works around an App Store submission bug triggered by universal binaries. It also copies the frameworks' .bcsymbolmap files into your target's .xcarchive. These .bcsymbolmap files are needed if you want to include app symbols in order for your application to receive symbolicated crash logs from Apple when you upload it to the App Store.

  1. (Optional but recommended) You may want to copy debug symbols for debugging and crash reporting. Add PSPDFKit.framework.dSYM and PSPDFKitUI.framework.dSYM to your Xcode project (do not add them to any targets — just add them to the tree) and add this folder as an input file to the Run Script Phase of step 2). The script will copy the debug symbols into the products directory and strip it from unneeded architectures. The dSYM files are part of the dmg download available at customers.pspdfkit.com for customers with an active license. They are not required and thus not part of the demo download.

Test Targets

If you need to integrate PSPDFKit in your test targets, just add PSPDFKit.framework and PSPDFKitUI.framework to the Link Binaries With Libraries build phase.

If you want to copy PSPDFKit into the build product (only needed in rare cases), you can add a Copy Files Phase in your test target's Build Phases with Frameworks as Destination. Then add PSPDFKit.framework and PSPDFKitUI.framework in there. (Non-application targets don't have an Embedded Binaries section, hence the Copy Files Phase.)

Sample Code for PSPDFViewController

It's really easy to present a PDF onscreen. All you need is to create a PSPDFDocument and then present it with a PSPDFViewController:

Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import PSPDFKit
import PSPDFKitUI

let fileURL = Bundle.main.url(forResource: "Document", withExtension: "pdf")!
let document = PSPDFDocument(url: fileURL)

let configuration = PSPDFConfiguration { builder in
    builder.thumbnailBarMode = .scrollable
    builder.isPageLabelEnabled = false
}

let pdfController = PSPDFViewController(document: document, configuration: configuration)

present(UINavigationController(rootViewController: pdfController), animated: true)
Copy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@import PSPDFKit;
@import PSPDFKitUI;

// Create the PSPDFDocument.
// This is the container for your PDF file. It can also manage multiple files.
NSURL *documentURL = [NSBundle.mainBundle URLForResource:@"Document" withExtension:@"pdf"];
PSPDFDocument *document = [[PSPDFDocument alloc] initWithURL:documentURL];

// Create the PDF view controller.
// The configuration object is optional and allows further customization.
PSPDFViewController *pdfController = [[PSPDFViewController alloc] initWithDocument:document configuration:[PSPDFConfiguration configurationWithBuilder:^(PSPDFConfigurationBuilder *builder) {
    builder.thumbnailBarMode = PSPDFThumbnailBarModeScrollable;
    builder.pageLabelEnabled = NO;
}]];

// Present the PDF view controller within an UINavigationController to enable the toolbar.
UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:pdfController];
[self presentViewController:navController animated:YES completion:NULL];

See our various example projects in the demo download dmg for further details.

Notes

While PSPDFDocument accepts an NSURL, only local PDF documents are supported. If you need to download them, look at the Kiosk example within PSPDFCatalog for some great example code.

PSPDFKit usually supports only the latest available Xcode version. If you see any compiler/linker errors, check if your Xcode version is current before contacting us.

If you're using manual retain/release instead of ARC and are getting warnings about missing property declarations of assign/retain, then adding -Wno-objc-property-no-attribute to the other C linker flags will resolve the issue.

Ensure that your application has all the required permissions set. See our Permissions article for details.

Troubleshooting

Library Not Found

If you followed the steps in our guide but still see an issue like this one:

Copy
1
2
3
dyld: Library not loaded: @rpath/PSPDFKit.framework/PSPDFKit
Referenced from: /Users/username/Library/Developer/CoreSimulator/Devices/51AB3B8F-37EA-454E-B9B3-3FCE92F9FD56/data/Containers/Bundle/Application/6D84096F-4239-450C-A3E2-48820ACC42EE/product.app/product
Reason: image not found

Then it's likely you have an older Xcode project where the Runpath Search Paths in your project settings are not correctly configured. Make sure they are set to the following value: $(inherited) @executable_path/Frameworks @loader_path/Frameworks.

PSPDFKit.bundle Issues

If you get a warning that is similar to this:

Error: The version of the PSPDFKit.bundle you're using (40412) does not match the version expected in PSPDFKit (50100). Please update the bundle to the version that ships with this version of PSPDFKit. Some features will not work until this is resolved

Then somewhere in your project an older copy of the PSPDFKit.bundle is referenced. Check your file tree and remove the old reference. This check ensures there's no outdated image/glyph metadata that could cause bugs in our SDK. We added an extra internal validation step to ensure the integration is correct and to save you from looming problems later on.

Version Control System File Size Limits

If you're running into an issue with your version control system because of PSPDFKit's file size, you can adopt one of the following solutions:

  • Use CocoaPods to integrate PSPDFKit. This way, you don't have to commit the framework.
  • Use GitHub's LFS to commit the framework.
  • (Since version 6.2.2) Remove bitcode by running PSPDFKit.framework/strip-bitcode.sh. This will remove about 100MB from the framework.
  • (Since version 6.2.2) Split the framework binary into smaller pieces:

Run PSPDFKit.framework/split-binary.sh to split the framework binary into the smaller pieces PSPDFKit-armv7, PSPDFKit-arm64, and PSPDFKit-iphonesimulator.

Now you can add the framework binary PSPDFKit.framework/PSPDFKit to your .gitignore and commit the smaller pieces instead.

You also need to add a new Run Script Phase in your target’s Build Phases to combine the pieces again.

IMPORTANT: Make sure this Run Script Phase is below the Target Dependencies build phase.
You can drag and drop build phases to rearrange them.

Call PSPDFKit.framework/combine-binaries.sh in this Run Script Phase's script text field. You can use $PROJECT_DIR, which points to the directory your Xcode project is contained in.
For example, if PSPDFKit.framework is in the same directory as your Xcode project, use the following:

1
bash "$PROJECT_DIR/PSPDFKit.framework/combine-binaries.sh"

Other Languages

We offer wrappers to use PSPDFKit with various other languages: