Image for How to easily display files like PDF, documents, images and more in your app

How to easily display files like PDF, documents, images and more in your app

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

If you need to let user view various files insider 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.

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

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. 🙂

QLPreviewController items list

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.

QLPreviewController demo

It can even show 3D models for ARKit 🙂

3D model preview in QLPreviewController

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

Thanks for reading!

Uses: Xcode 11 & Swift 5