Image for How to display files like PDFs, documents, GIFs, images and more in your app

How to display files like PDFs, documents, GIFs, images and more in your app

Short guide demonstrating how to use QLPreviewController for easy file previews. It even supports ARKit models!

Published: May 22, 2020
App Store

If you need to let user view various files inside your app, iOS offers pretty nice solution called QLPreviewController. "QL" stands for the Quick Look framework which is used in iOS and macOS to preview files.

This view controller can preview various types of files. PDFs, Word documents, Pages documents, Keynote presentations, GIFs, images, ARKit models and more.

In this blog post I will show you basic usage of QLPreviewController and you can also check out my example project at the bottom of the post. The first step is to import the framework:

import QuickLook

Conforming to delegate

And then conform to the QLPreviewControllerDataSource protocol. This requires we implement couple of methods. These are:

func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
}

func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
}

This is a bit like Table View data source. We need to tell QLPreviewController how many items we want to preview and return preview item for specific index.

If you have multiple preview items the QLPreviewController will take care of them, show the total and let user swipe horizontally to move among them and also displays them in a list. Pretty neat. 🙂

Displaying PDFs, GIFs, documents and more

Creating QLPreviewItem

What about QLPreviewItem? It is a small protocol we can implement on our model classes. It has only one required property and that is previewItemURL: URL? which needs to point to the file we want to preview.

Optionally you can also provide previewItemTitle: String? to have custom name, otherwise the last part of the file URL is used.

Below is my implementation from the example project:

class Preview: NSObject, QLPreviewItem {
    let displayName: String
    let fileName: String
    let fileExtension: String

    init(displayName: String, fileName: String, fileExtension: String) {
        self.displayName = displayName
        self.fileName = fileName
        self.fileExtension = fileExtension

        super.init()
    }

    var previewItemTitle: String? {
        return displayName
    }

    var previewItemURL: URL? {
        return Bundle.main.url(forResource: fileName, withExtension: fileExtension)
    }
} 

I am using files added to the project, so getting their URLs is done via Bundle.main.

Let's create instance of the preview controller:

let previewVC = QLPreviewController()

And set its dataSource inside viewDidLoad():

previewVC.dataSource = self

I am using Table View to list all files in my example and this is the didSelectRowAt implementation:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        previewVC.currentPreviewItemIndex = indexPath.row
        navigationController?.pushViewController(previewVC, animated: true)
}

I am setting the currentPreviewItemIndex to the index of item selected from Table View and then pushing instance of QLPreviewController to the navigation stack.

Finished example

Displaying PDFs, GIFs, documents example

It can even show 3D models for ARKit 🙂

And that is the basic implementation done. You can check the example project on GitHub.

Thanks for reading!

Uses: Xcode 12 & Swift 5.3

Filip Němeček profile photo

WRITTEN BY

Filip Němeček @nemecek_f@iosdev.space

iOS blogger and developer with interest in Python/Django. Want to see most recent projects? 👀

iOS blogger and developer with interest in Python/Django. Want to see most recent projects? 👀