Search code examples
iosswiftswift5wknavigationdelegate

WKWebView is empty if I implement decidePolicyFor navigationAction, loads correctly if I remove the function


This is in xcode 10.3, swift 5

I'm trying to load some web content using WKWebView. I have a class that is just NSObject, which implements the WKNavigationDelegate class.

  • I create the web view
  • Set the navigationDelegate
  • Load the web view

If I include this function: (allow anything)

    public func webView(_ webView: WKWebView,
                        decidePolicyFor navigationAction: WKNavigationAction,
                        decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {

        decisionHandler(.allow)
        return
    }

The page just loads an empty html body and nothing is ever displayed. Also the function never appears to be called this way.

If I comment out that function, the page loads normally.

I am stumped!

I have tried changing my class which contains the webview to be a UIViewController, and then add it to the main controller. Doing that, the decision handler function does get called, but my webview is still empty. (it only ever asks for about:blank)

// simplified code

public class MyClass : NSObject, WKUIDelegate, WKNavigationDelegate {
    public func load(container:UIView){
        let config = WKWebViewConfiguration()
        config.allowsInlineMediaPlayback = true
        config.mediaTypesRequiringUserActionForPlayback = WKAudiovisualMediaTypes.init(rawValue: 0)

        webView = WKWebView(frame:CGRect(x:0, y:0, width:250, height:250), configuration: config) // test rectangle
        webView!.navigationDelegate = self
        webView!.uiDelegate = self
        webView!.isUserInteractionEnabled = true
        container.addSubview(webView!)

        let body = "<div>test</div>"
        webView!.loadHTMLString(body, baseURL:URL(string:"MY_SITE_HERE"))
    }

    public func webView(_ webView: WKWebView,
                        decidePolicyFor navigationAction: WKNavigationAction,
                        decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {

        decisionHandler(.allow)
        return
    }
}


How this comes about: My main view controller has an instance of an NSObject, which does the following simplified:


class SDKConsumer : NSObject {

init(parentViewController:ViewController) {
        self.parentViewController = parentViewController
        super.init()
    }

func myFunction(){
        let instance = MyClass()

        instance.load(container:parentViewController!.view)
    }
}

Solution

  • You have a memory management issue. You are not keeping a strong reference to the MyObject instance anywhere. As soon as myFunction ends, the MyObject instance goes away since there are no strong references.

    Make instance a property instead of a local variable and your problem should be resolved.