iOS: How to easily display files like PDF, documents, images and more in your app
Tags: ios, swift
Published: 2020-03-28 13:07:16

If you need to let user view various files insider your app, iOS offers pretty nice solution called [QLPreviewController](https://developer.apple.com/documentation/quicklook/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:

```swift
import QuickLook
```

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

```swift
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](https://dev-to-uploads.s3.amazonaws.com/i/7ttzz24adl10hdj0uhv3.jpeg)

### `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:

```swift
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:

```swift
let previewVC = QLPreviewController()
```

And set its `dataSource` inside `viewDidLoad()`:

```swift
previewVC.dataSource = self
```

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

```swift
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](https://dev-to-uploads.s3.amazonaws.com/i/8cvrujhlfgqr0j4jkgi4.gif)

It can even show 3D models for ARKit 🙂

![3D model preview in QLPreviewController](https://dev-to-uploads.s3.amazonaws.com/i/2aa9l3hgya8booqp1tgl.gif)

And that is the basic implementation done. You can check the example project on [GitHub](https://github.com/nemecek-filip/QLPreviewController.Example).

_Thanks for reading!_



[![Scan it - wide banner](https://nemecek.be/media/images/scanItWideBanner.png)](https://apps.apple.com/app/scan-it-scan-and-export-pdf/id1509634112)