Present preview of downloaded file directly in app

4.4k views Asked by At

My application have file download option which downloads the file using alamofire download method. When the download completes i need to present the preview of the file without saving it to internal/cloud storage. How can i achieve this whatsapp like function that shows the preview after downloading the file.

func downloadFile(fileUrl: URL) {
    let destination = DownloadRequest.suggestedDownloadDestination(for: .documentDirectory)

    Alamofire.download(fileUrl, to: destination)
        .response(completionHandler: { (downloadResponse) in
            self.dic.url = downloadResponse.destinationURL
            self.dic.uti = downloadResponse.destinationURL!.uti
            let rect = CGRect(x: 0, y: 0, width: 100, height: 100)
            self.dic.presentOpenInMenu(from: rect, in: self.view, animated: true)
        })
}
2

There are 2 answers

0
Vaisakh KP On BEST ANSWER

To present a preview of a file use Appleā€™s QuickLook framework that lets you embed previewing for a huge range of file types, including iWork documents, Microsoft Office documents, PDFs, images, and more, all without writing much code.

First, import the QuickLook framework, then make your view controller conform to the QLPreviewControllerDataSource protocol.

Reference:

  1. https://www.hackingwithswift.com/example-code/libraries/how-to-preview-files-using-quick-look-and-qlpreviewcontroller

  2. https://github.com/gargsStack/QLPreviewDemo

  3. https://www.appcoda.com/quick-look-framework/

Code:

class ViewController: UIViewController {
    var previewItem = URL!

    func downloadFile(fileUrl: URL) {
        let destination = DownloadRequest.suggestedDownloadDestination(for: .documentDirectory)

        Alamofire.download(fileUrl, to: destination)
        .response(completionHandler: { (downloadResponse) in

            let previewController = QLPreviewController()
            previewController.dataSource = self
            self.previewItem = downloadResponse.destinationURL
            self.present(previewController, animated: true, completion: nil)
        })
    }
}

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

    func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
       return self.previewItem as QLPreviewItem
    }
}
0
Shourob Datta On

Here is one solution using Alamofire. Someone may help.

Steps:

  • Alamofire has excellent staff to direct download and also save/write your file into disc.

  • Return a path where downloaded file saved.

  • Using UIDocumentInteractionController pass the file path

  • Then present this view

     import Alamofire
    
         extension UIViewController : UIDocumentInteractionControllerDelegate{
    
    
         func downloadFileForPreview(fileName: String, fileExtension: String, filePath: String )  {
    
    
             let destination: DownloadRequest.DownloadFileDestination = { _, _ in
                 let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
    
                 let fileWithExtension = "file.\(fileExtension)"
    
                 let fileURL = documentsURL.appendingPathComponent(fileWithExtension)
    
                 return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
             }
             //UtilitySwift.showUniversalLoadingView(true)
             Alamofire.download(filePath, to: destination).response {  response in
                 debugPrint(response)
             //UtilitySwift.showUniversalLoadingView(false)
    
                 if response.error == nil, let storeFilePath = response.destinationURL?.path {
                     //let image = UIImage(contentsOfFile: imagePath)
                     self.previewDocument(withFilePath: response.destinationURL)
                     print(storeFilePath)
    
                 }
    
                 else{
                     UtilitySwift.showErrorMessage(message: response.error?.localizedDescription ?? "Error occured when downloading" )
                     print(response.error?.localizedDescription ?? "")
                 }
    
             }
         }
    
    
         //  Converted to Swift 5.1 by Swiftify v5.1.29672 - https://objectivec2swift.com/
         func previewDocument(withFilePath filePath: URL?) {
    
             var documentInteractionController: UIDocumentInteractionController?
    
             if filePath != nil {
                 // Initialize Document Interaction Controller
                 if let filePath = filePath {
                     documentInteractionController = UIDocumentInteractionController(url: filePath)
                 }
    
                 // Configure Document Interaction Controller
                 documentInteractionController?.delegate = self as UIDocumentInteractionControllerDelegate
    
                 //if not possible to open
                 if !documentInteractionController!.presentPreview(animated: true) {
                     documentInteractionController?.presentOptionsMenu(from: CGRect.zero, in: self.view, animated: true)
                 }
    
             } else {
                 // error
                 print("file preview error")
             }
         }
         //UIDocumentInteractionControllerDelegate
         public func documentInteractionControllerViewControllerForPreview(_ controller: UIDocumentInteractionController) -> UIViewController {
             self
         }
    
         }
    

Call from any UIViewController

self.downloadFileForPreview(fileName: "file", fileExtension: fileExt ?? "", filePath: REPLACE_WITH_DOWNLOAD_URL)

enter image description here