0

I have downloaded a pdf file to my cache memory.Now I wish to open this PDF file in a PDFView. I have added a PDFView to my ViewController, here is the code for the same.

let pdfView = PDFView()
override func viewDidLoad() {
   super.viewDidLoad()
   view.addSubview(pdfView)
}

The below given code will return the location to which the PDF was downloaded as a URL.

guard let pdfURL = downloader.downloadData(urlString: "https://www.tutorialspoint.com/swift/swift_tutorial.pdf", downloadType: DownloadType.cache.rawValue) else { return }

I have checked the URL given back and the file exists. Now in the following code I am trying to open it in the pdf view.

if let document = PDFDocument(url: pdfURL) {
   pdfView.document = document
}

Below given code shows the download data method.

public func downloadData(urlString : String,downloadType : String)->URL?{

        let documentsUrl:URL =  FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first as URL!
        var destinationFileUrl = documentsUrl.appendingPathComponent("downloadedFile.pdf")
        try? FileManager.default.removeItem(at: destinationFileUrl)
        guard let url = URL(string: urlString)else{
            return nil
        }
        let urlSession = URLSession(configuration: .default)
        let downloadTask = urlSession.downloadTask(with: url) { (tempLocalUrl, response, error) in
            if let tempLocalUrl = tempLocalUrl, error == nil {

                if let statusCode = (response as? HTTPURLResponse)?.statusCode {
                    print("Successfully downloaded. Status code: \(statusCode)")

                }
                if downloadType == "cache" {
                    do {
                        try? FileManager.default.removeItem(at: destinationFileUrl)
                          try FileManager.default.copyItem(at: tempLocalUrl, to: destinationFileUrl)
                    } catch (let writeError) {
                        print("Error creating a file \(destinationFileUrl) : \(writeError)")
                    }
                }
            } else {
                print("Error took place while downloading a file. Error description: %@", error?.localizedDescription);
            }
        }
        downloadTask.resume()

        return destinationFileUrl
    }

But it seems like it is returning nil and the code inside if let block is not executed. Please Help!!

Raj Mohan
  • 47
  • 1
  • 9
  • The `downloader.downloadData` is asynchronously. You can not get the url synchronously. To get it in its `delegate` – dengApro Oct 31 '19 at 08:27
  • Thank you for suggestion.Even though I am doing it asynchronously I am getting a valid url to the downloaded file in which the file do exists but why am not able to pass the url to thePDFDocument()?Any thoughts on that?@dengApro – Raj Mohan Oct 31 '19 at 09:10
  • https://stackoverflow.com/questions/50383343/urlsession-download-from-remote-url-fail-cfnetworkdownload-gn6wzc-tmp-appeared – dengApro Oct 31 '19 at 09:38
  • @dengApro I have updated the post please have a look at downloadData() – Raj Mohan Oct 31 '19 at 11:10

1 Answers1

1

Nil of course. return destinationFileUrl, use it to init PDF, gets nil.

it returns, While the task is still executing, so the file in the path not exists.

Because downloading is an asynchronous action.

So here is completionHandler closure for.

Ususlly, turn this

public func downloadData(urlString : String,downloadType : String)->URL?{

        let documentsUrl:URL =  FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first as URL!
        var destinationFileUrl = documentsUrl.appendingPathComponent("downloadedFile.pdf")
        try? FileManager.default.removeItem(at: destinationFileUrl)
        guard let url = URL(string: urlString)else{
            return nil
        }
        let urlSession = URLSession(configuration: .default)
        let downloadTask = urlSession.downloadTask(with: url) { (tempLocalUrl, response, error) in
            if let tempLocalUrl = tempLocalUrl, error == nil {

                if let statusCode = (response as? HTTPURLResponse)?.statusCode {
                    print("Successfully downloaded. Status code: \(statusCode)")

                }
                if downloadType == "cache" {
                    do {
                        try? FileManager.default.removeItem(at: destinationFileUrl)
                          try FileManager.default.copyItem(at: tempLocalUrl, to: destinationFileUrl)
                    } catch (let writeError) {
                        print("Error creating a file \(destinationFileUrl) : \(writeError)")
                    }
                }
            } else {
                print("Error took place while downloading a file. Error description: %@", error?.localizedDescription);
            }
        }
        downloadTask.resume()


        return destinationFileUrl
    }

into

public func downloadData(urlString : String,downloadType : String, completionHandler: @escaping (URL) -> Void){

            let documentsUrl:URL =  FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first as URL!
            var destinationFileUrl = documentsUrl.appendingPathComponent("downloadedFile.pdf")
            try? FileManager.default.removeItem(at: destinationFileUrl)
            guard let url = URL(string: urlString)else{
                return nil
            }
            let urlSession = URLSession(configuration: .default)
            let downloadTask = urlSession.downloadTask(with: url) { (tempLocalUrl, response, error) in
                if let tempLocalUrl = tempLocalUrl, error == nil {

                    if let statusCode = (response as? HTTPURLResponse)?.statusCode {
                        print("Successfully downloaded. Status code: \(statusCode)")

                    }
                    if downloadType == "cache" {
                        do {
                            try? FileManager.default.removeItem(at: destinationFileUrl)
                              try FileManager.default.copyItem(at: tempLocalUrl, to: destinationFileUrl)
                                completionHandler(destinationFileUrl)
                        } catch (let writeError) {
                            print("Error creating a file \(destinationFileUrl) : \(writeError)")
                        }
                    }
                } else {
                    print("Error took place while downloading a file. Error description: %@", error?.localizedDescription);
                }
            }
            downloadTask.resume()

        }

In the completionHandler call back , init the PDF

dengApro
  • 3,848
  • 2
  • 27
  • 41