Is there a specific way to listen to the completio

2019-07-11 07:45发布

问题:

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?

回答1:

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.