iosswiftxcodequicklook

How to display pdf from network in iOS


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)
 }
}

Solution

  • 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