WKWebView Delegate WKNavigationDelegate fails to set properly in production

268 Views Asked by At

We have detected in production that there are times when we try to set the WKNavigationDelegate of the WKWebView, but that even though the object we are assigning to the delegate is not nil and is a valid allocated instance of WKNavigationDelegate the result of the command to set the delegate is that the web view's delegate remains nil.

Essentially as a step-by-step, what happens is:

  • Create and retain a WKWebView: "self.webView = WKWebView()"
  • set self as the navigation delegate: "self.webView.navigationDelegate = self"
  • record to remote logging if this assignment has been successful: "operationalLogger.webViewDelegates(webview.navigationDelegate != nil)"

We are observing in our logging that in ~7% of cases, the webview.navigationDelegate is equal to nil, even after assigning a fully allocated WKNavigationDelegate object to the instance.

A class where we set the delegate:

import WebKit

class WebViewContainer: NSObject {
    
    private static var sharedInstance: WebViewContainer?
    
    let webView: WKWebView
    var webViewContainerNavigationDelegate: WKNavigationDelegate?
    var webViewContainerUIDelegate: WKUIDelegate?
    
    // Use this standard init function to create a new instance
    init(config: WKWebViewConfiguration?) {
        
        if let configExists = config {
            self.webView = WKWebView(frame: .zero, configuration: configExists)
        } else {
            self.webView = WKWebView()
        }
        
        super.init()
        self.webView.navigationDelegate = self
        self.webView.uiDelegate = self
    }
    
    // Use this shared function to use a Singleton instance
    static func shared(config: WKWebViewConfiguration?) -> WebViewContainer {
        
        guard let existingInstance = sharedInstance else {
            let newShared = WebViewContainer(config: config)
            sharedInstance = newShared
            return newShared
        }
        
        return existingInstance
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

extension WebViewContainer: WKNavigationDelegate {
// Implemented WKNavigationDelegate here
}

Please note that this Container class has been created to test if the success rate improves when we use a Singleton WKWebView. However, this does not improve the result.

Unfortunately, I'm unable to reproduce this locally, but I can see from our logs that in ~7% of cases, our users are affected by this issue.

Has anyone seen an issue like this? Or have any tips on how to ensure that the WKNavigationDelegate is assigned correctly 100% of the time?

0

There are 0 best solutions below