3

I have implemented a Custom PDFView that loads pdf files from the cloud and locally if available. For local instances as expected everything loads fast, but when the url is not local i.e from the server it may take a while, I'd like to add an UIActivityIndicator while the PDFView loads the file, is there a way for us to know like a delegate or a notification to listen to to keep track of this?

My implementation is basically like below:

let url = ReportsRepository.shared.getReportUrl(id: "1234")

self.pdfView.document = PDFDocument(url: url)

After this, if the URL is from the server the application seems to freeze, so I need to add a UIActivityIndicator here, the problem is how would I stop it using the PDFKit?

Jojo Narte
  • 2,767
  • 2
  • 30
  • 52

2 Answers2

5

I have done using background queue. Here is my code.

//Some loading view here
    DispatchQueue.global(qos: .background).async {

        if let url = URL(string: self.selectedWebUrl) {
            if let pdfDocument = PDFDocument(url: url) {
                DispatchQueue.main.async {
                   //Load document and remove loading view
                    self.pdfView.displayMode = .singlePageContinuous
                    self.pdfView.autoScales = true
                    self.pdfView.displayDirection = .vertical
                    self.pdfView.document = pdfDocument

                }
            } else {
                DispatchQueue.main.async {
                    //not able to load document from pdf
                    //Remove loading view

                }
            }
        } else {
            DispatchQueue.main.async {
                //Wrong Url show alert or something
                //Remove loading view

            }
        }
    }
Noman Haroon
  • 185
  • 1
  • 11
2

Another way to load your PDFDocument is to pass in raw data.

If this were my problem, I'd load the data asynchronously via a method like this:

func loadAndDisplayPDF() {

    // file on the local file system
    let requestURL = URL(fileURLWithPath: "/tmp/MyResume.pdf")! 

    // remote pdf
    //let requestURL = URL(string: "http://www-personal.umich.edu/~myke/MichaelDautermannResume.pdf")!
    let urlRequest = URLRequest(url: requestURL)
    let session = URLSession.shared

    if requestURL.isFileURL == false {
        print("this is a good place to bring up a UIActivityIndicator")
    }
    let task = session.dataTask(with: urlRequest) {
        (data, response, error) -> Void in

        if let actualError = error
        {
            print("loading from \(requestURL.absoluteString) - some kind of error \(actualError.localizedDescription)")
        }

        if let httpResponse = response as? HTTPURLResponse
        {
            let statusCode = httpResponse.statusCode

            if (statusCode == 200) {
                print("file downloaded successfully.")
            } else  {
                print("Failed")
            }
        }

        if let actualData = data {
            print("data length is \(actualData.count)")
            self.pdfView = PDFView(frame: CGRect(x: 10, y: 10, width: 200, height: 200))
            if let actualPDFView = self.pdfView {
                actualPDFView.document = PDFDocument(data: actualData)
                self.view = actualPDFView
            }
        }
        print("all done")
    }
    task.resume()
}

You could either display the UIActivityIndicator immediately (when you detect it's remote) or you could set a timer to fire after 1/2 - 1 second, invalidate and/removing both as the PDF file is about to display.

Michael Dautermann
  • 88,797
  • 17
  • 166
  • 215
  • this seems plausible, I havent tried it yet but it makes sense. I'll let you know when I got the chance to test it out. – Jojo Narte May 25 '18 at 15:22