Jack Robson Jack Robson -5 years ago 188
Swift Question

Add A Callback To A Prebuilt Asynchronous Function Swift iOS

I'm messing around with pdfs at the moment. I'm attempting to load a PDF into the system and write out the same PDF to gain an understandings of the the whole procedure.

The problem I've got it is that I'm having to load the pdf from the web and because the WebViewUI.loadRequest is asynchronous, it isn't completed in time.

override func viewDidLoad() {

let filePath = getDocumentsDirectory().stringByAppendingPathComponent("output.pdf")

let url : NSURL! = NSURL(string: "http://www.nhs.uk/NHSEngland/Healthcosts/Documents/2014/HC5(T)%20June%202014.pdf")

loadTemplate(url, completion: {(webView: UIWebView) -> Void in
print("callback started")
let pdf = self.toPDF(webView)

do {
pdf!.writeToFile(filePath, atomically: true)
} catch {
// failed to write file – bad permissions, bad filename, missing permissions, or more likely it can't be converted to the encoding

print("callback started")


print("Finished viewDidLoad")


func loadTemplate(url: NSURL, completion: (webView: UIWebView) -> Void) {
print("Start loadTemplate")
// do some crunching to create the SketchAnimation instance...
let webView = UIWebView(frame: CGRectMake(20, 100, 300, 40))
webView.loadRequest(NSURLRequest(URL: url))


// invoke the completion callback
completion(webView: webView)

print("finished loadTemplate")

How do I add a callback to the loadRequest instead of loadTemplate?

Answer Source

You don't, exactly. You'd set up your view controller to be the web view's delegate and implement the webViewDidFinishLoad method. In that method you'd check to make sure the load that finished is the one you were after, and if so, then you'd invoked the code you want to run when the load is complete.

Here is a basic example of how to set that up:

//  ViewController.swift

import UIKit

class ViewController: UIViewController, UIWebViewDelegate {

    @IBOutlet var webView: UIWebView!

    var url = NSURL(string: "http://google.com")

    override func viewDidLoad() {

        //load initial URL
        let req = NSURLRequest(URL : url!)
        webView.delegate = self

    func webViewDidStartLoad(webView : UIWebView) {

    func webViewDidFinishLoad(webView : UIWebView) {

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download