Blog Post

How to show a PDF in SwiftUI

Illustration: How to show a PDF in SwiftUI

Apple announced SwiftUI at WWDC19 last week, and we’re very excited about it. SwiftUI is Apple’s declarative framework for quickly creating user interfaces in Swift on all Apple platforms.

We immediately got started with Apple SwiftUI tutorials: We bridged Apple’s PDFKit PDFView and PSPDFViewController from Nutrient to SwiftUI, and we saw great results within an hour!

In this article, we’ll discuss how to show a PDF document in SwiftUI. In the first part, we’ll cover how we can use Apple’s PDFKit API to display a PDF in SwiftUI. In the second part, we’ll see how our iOS PDF Library can be used to render a PDF in SwiftUI in a few simple steps.

pspdfkit-swiftui

Prerequisites

  • Xcode 11

  • iOS device running iOS 13 or the iOS Simulator

  • Nutrient iOS SDK

Getting started

  • Download the sample project here.

  • If you’re an existing customer, download our iOS PDF library from the Nutrient Portal . Otherwise, if you don’t already have Nutrient, get our free trial.

  • Copy PSPDFKit.xcframework and PSPDFKitUI.xcframework into PSPDFKitSwiftUI/PSPDFKit in the sample project directory.

  • Open PSPDFKitSwiftUI.xcodeproj in Xcode 11 and run it.

The rest of this post will walk you through the steps we went through to create the sample project.

Showing a PDF using Apple’s PDFKit

Let’s first discuss how to show a PDF in SwiftUI using Apple’s PDFKit.

Bridging PDFView to SwiftUI

We begin by declaring the PDFKitRepresentedView struct, which conforms to the UIViewRepresentable protocol, so that we can bridge from UIKit to SwiftUI. After that, we add a property of type URL and implement the protocols as seen below:

struct PDFKitRepresentedView: UIViewRepresentable {
    let url: URL

    init(_ url: URL) {
        self.url = url
    }

    func makeUIView(context: UIViewRepresentableContext<PDFKitRepresentedView>) -> PDFKitRepresentedView.UIViewType {
        // Create a `PDFView` and set its `PDFDocument`.
        let pdfView = PDFView()
        pdfView.document = PDFDocument(url: self.url)
        return pdfView
    }

    func updateUIView(_ uiView: UIView, context: UIViewRepresentableContext<PDFKitRepresentedView>) {
        // Update the view.
    }
}

Creating the SwiftUI view

As the next step, we declare PDFKitView (the SwiftUI view) with the URL property, like so:

struct PDFKitView: View {
    var url: URL

    var body: some View {
        PDFKitRepresentedView(url)
    }
}

Using PDFKitView in SwiftUI

We can now use PDFKitView in our SwiftUI content view:

struct ContentView: View {
	let documentURL = Bundle.main.url(forResource: "PSPDFKit 9 QuickStart Guide", withExtension: "pdf")!
	var body: some View {
		VStack(alignment: .leading) {
			Text("PSPDFKit SwiftUI")
				.font(.largeTitle)
			HStack(alignment: .top) {
				Text("Made with ❤ at WWDC19")
					.font(.title)
			}
			PDFKitView(url: documentURL)
		}
	}
}

Showing a PDF using Nutrient iOS SDK

Apple’s PDFKit provides a great starting point for integrating PDF support into your iOS app. Nutrient, on the other hand, is a cross-platform PDF framework with more advanced features, fine-grained control over various aspects of PDF handling, and plenty of customization options. Please take a look at our iOS guides for more details.

Now, let’s talk about how to show a PDF in SwiftUI using Nutrient iOS SDK.

Bridging PSPDFViewController to SwiftUI

First, declare the PDFViewController struct — which conforms to the UIViewControllerRepresentable protocol — so that you can bridge from UIKit to SwiftUI. After that, add a property of type PSPDFConfiguration and implement the protocols as seen below:

struct PDFViewController: UIViewControllerRepresentable {
    let url: URL
    let configuration: PSPDFConfiguration?

    init(_ url: URL, configuration: PSPDFConfiguration?) {
        self.url = url
        self.configuration = configuration
    }

    func makeUIViewController(context: UIViewControllerRepresentableContext<PDFViewController>) -> UINavigationController {
        // Create a `PSPDFDocument`.
        let document = PSPDFDocument(url: url)

        // Create the `PSPDFViewController`.
        let pdfController = PSPDFViewController(document: document, configuration: configuration)
        return UINavigationController(rootViewController: pdfController)
    }

    func updateUIViewController(_ uiViewController: UINavigationController, context: UIViewControllerRepresentableContext<PDFViewController>) {
        // Update the view controller.
    }
}

Creating the SwiftUI view

In the following step, declare PDFView (the SwiftUI view) with the URL and the optional PSPDFConfiguration properties, like so:

struct PSPDFKitView: View {
    var url: URL
    var configuration: PSPDFConfiguration?

    var body: some View {
        PDFViewController(url, configuration: configuration)
    }
}

Using PSPDFKitView in SwiftUI

And finally, use PSPDFKitView in your SwiftUI content view:

struct ContentView: View {
    let documentURL = Bundle.main.url(forResource: "PSPDFKit 9 QuickStart Guide", withExtension: "pdf")!
    let configuration = PSPDFConfiguration {
        $0.pageTransition = .scrollContinuous
        $0.pageMode = .single
        $0.scrollDirection = .vertical
        $0.backgroundColor = .white
    }
    var body: some View {
		VStack(alignment: .leading) {
			Text("PSPDFKit SwiftUI")
				.font(.largeTitle)
			HStack(alignment: .top) {
				Text("Made with ❤ at WWDC19")
					.font(.title)
			}
			PSPDFKitView(url: documentURL, configuration: configuration)
		}
	}
}

That’s all! Here it is in action:

Conclusion

We were very impressed with how quickly we could implement user interfaces with SwiftUI. We plan to officially support SwiftUI in Nutrient in the fall.

Update: We added support for SwiftUI in Nutrient iOS SDK 9 and enhanced our support for it in Nutrient iOS SDK 10.1. See our SwiftUI guide for more information.

We saw in this post that using SwiftUI and Apple’s PDFKit is a good starting point for displaying a PDF in your iOS app and is a great solution for many use cases. However, sometimes your business requires more advanced features, such as PDF annotations, digital signatures, or PDF form filling.

If your business relies on the above or other advanced use cases, consider looking at commercial alternatives. At Nutrient, we offer a feature-rich and completely customizable iOS PDF SDK with well-documented APIs to handle complex use cases. Try out our PDF library using our free trial, and check out our demos to see what’s possible.

FAQ

Here are a few frequently asked questions about showing a PDF in SwiftUI.

How do I display a PDF in SwiftUI?

You can use Apple’s PDFKit by bridging PDFView to SwiftUI using UIViewRepresentable.

Can I use Nutrient in a SwiftUI app?

Yes, Nutrient can be integrated into SwiftUI by bridging PSPDFViewController with UIViewControllerRepresentable.

What features does Nutrient offer beyond PDFKit?

Nutrient provides advanced features like annotations, form filling, and digital signatures, which are not available in PDFKit.

Do I need Nutrient for simple PDF viewing in iOS?

For basic PDF viewing, PDFKit is sufficient. Nutrient is useful for more complex use cases.

Is Nutrient compatible with all iOS devices?

Yes, Nutrient supports iOS devices running the required iOS versions.

Related products
Share post
Free trial Ready to get started?
Free trial