0

Currently I am using QuickLook module to open pdf from network, but it shows a blank page with error "Couldn't issue file extension for url: https://testing-xamidea.s3.amazonaws.com/flowchart/20171103182728150973368.pdf" in console. I guess QuickLook can only open locally saved Pdf files. Is is possible to load pdf from network using quicklook? . This is my code so far- {fileURL contains url from which pdf is to be loaded, also ive set the delegates etc)

extension FlowchartVC:QLPreviewControllerDelegate,QLPreviewControllerDataSource {
func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
return 1
 }  
func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {

let url : NSURL! = NSURL(string : fileURL)
return url
 }
   func previewControllerWillDismiss(_ controller: QLPreviewController) {
 self.dismiss(animated: true, completion: nil)
 }
}
Romit Kumar
  • 2,442
  • 6
  • 21
  • 34

1 Answers1

7

You need to save the file to disk first and then you can present the pdf. There is no way to present it with QuickLook if the file is in a remote location. The file is saved in the temporary directory. Here is an example view controller showing how it could be done.

Swift 5:

import UIKit
import QuickLook

class ViewController: UIViewController, QLPreviewControllerDataSource {
    // Remote url pdf I found on google
    let itemURL = URL(string: "https://www.ets.org/Media/Tests/GRE/pdf/gre_research_validity_data.pdf")!
    var fileURL: URL?
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        let quickLookController = QLPreviewController()
        quickLookController.dataSource = self

        do {
            // Download the pdf and get it as data
            // This should probably be done in the background so we don't
            // freeze the app. Done inline here for simplicity
            let data = try Data(contentsOf: itemURL)

            // Give the file a name and append it to the file path
            fileURL = FileManager().temporaryDirectory.appendingPathComponent("sample.pdf")
            if let fileUrl = fileURL {
                // Write the pdf to disk in the temp directory
                try data.write(to: fileUrl, options: .atomic)
            }
            
            // Make sure the file can be opened and then present the pdf
            if QLPreviewController.canPreview(fileUrl as QLPreviewItem) {
                quickLookController.currentPreviewItemIndex = 0
                present(quickLookController, animated: true, completion: nil)
            }
        } catch {
            // cant find the url resource
        }
    }
    
    func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
        return 1
    }
    
    func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
        return fileURL! as QLPreviewItem
    }
}

Swift 3:

import UIKit
import QuickLook

class ViewController: UIViewController, QLPreviewControllerDataSource {
    // Remote url pdf I found on google
    let itemURL = URL(string: "https://www.ets.org/Media/Tests/GRE/pdf/gre_research_validity_data.pdf")!
    var fileURL = URL(string: "")

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        let quickLookController = QLPreviewController()
        quickLookController.dataSource = self

        do {
            // Download the pdf and get it as data
            // This should probably be done in the background so we don't
            // freeze the app. Done inline here for simplicity
            let data = Data(contentsOf: itemURL)

            // Give the file a name and append it to the file path
            fileURL = FileManager().temporaryDirectory.appendingPathComponent("sample.pdf")
            // Write the pdf to disk
            try data?.write(to: fileURL!, options: .atomic)

            // Make sure the file can be opened and then present the pdf
            if QLPreviewController.canPreview(fileUrl as QLPreviewItem) {
                quickLookController.currentPreviewItemIndex = 0
                present(quickLookController, animated: true, completion: nil)
            }
        } catch {
            // cant find the url resource
        }
    }

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

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

Here is the file showing in the simulator. Using a sample project with just that code.

enter image description here

Nordeast
  • 1,353
  • 13
  • 21
  • First you are supposed to use Data instead of NSData since Swift3. Second don't use Data(contentsOf: URL) to load non resource file url synchronously. It would freeze the app in case there is no internet connection. Third you can just use the temporary directory instead of manually deleting the file after displaying it. Check the duplicated question that was asked and answered earlier today. https://stackoverflow.com/questions/47140314/how-to-display-remote-document-using-qlpreviewcontroller-in-swift – Leo Dabus Nov 06 '17 at 18:41
  • Btw when overriding `viewDidAppear` method you are supposed to call `super.viewDidAppear(animated)` instead of `super.viewDidLoad()`. – Leo Dabus Nov 06 '17 at 18:47