Search code examples
swift3uiwebviewuiwebviewdelegate

Swift UIWebView Delegate use and override shouldStartLoadWith


I am writing a reusable UIWebView controller and want to descend from that while using the delegate shouldStartLoadWith function and override it as well but I'm not sure how to do it.

In my reusable UiWebView controller I have this.

func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {

    let docURLStr = request.mainDocumentURL!.absoluteString

    if docURLStr.contains("login") {
       loadLoginView()
        return false
    }

Then in my child class I want to do the following but I want to use both functions.How can I do that?

override func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {

let docUrl = request.url!.absoluteString

if String(describing: docUrl).range(of: "some string in the url") != nil{
     return true
     } else {
       return false
       }
}

Solution

  • You could simply use the super implementation and combine the two using a logical or or and, depending on what you want to achieve:

    override func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool
    {
        let docUrl = request.url!.absoluteString
        let load = String(describing: docUrl).range(of: "some string in the url") != nil
        return load || super.webView(webView, shouldStartLoadWith: request, navigationType: navigationType)
    }
    

    To check for several strings you might do something like this:

    override func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool
    {
        let docUrl = request.url!.absoluteString
        let superWantsToLoad = super.webView(webView, shouldStartLoadWith: request, navigationType: navigationType)
        let strings = ["foo", "bar"]
        return superWantsToLoad || strings.contains(where: { docUrl.contains($0) })
    }
    

    Please note that the string.contains() call will only be evaluated if superWantsToLoad is false thanks to short-circuit evaluation. This could be important if you have many strings to handle. (Alternatively, you could insert an early return true.)