Load Custom Error HTMLstring When Wkwebview Loadrequest Fails

WKWebView in iOS app takes a long time to load

Apparently the delay is caused by the time it takes to make a new instance of WKWebView, not the time it takes to load an HTML document. To avoid that delay I figured out a way to reuse a web view.

First I removed the web view from the storyboard scene so that a new web vew wouldn't be created every time the view was loaded. I made a generic view named container that is the same size that I wanted the web view to be.

Then I made a static variable to keep a pointer to the web view:

static var webView: WKWebView? = nil
In my case this static variable is in a class called GameController.

Next I changed the code to check to see if the static webView variable is nil. If webView is nil, the code creates a new web view and sets the static variable to point to that web view. Then the code programmatically adds the web view as a subview of a container view in the storyboard scene.

To set up the storyboard and write this code I used the explanation on the following web site:

http://www.onebigfunction.com/ios/2016/12/14/iOS-javascript-communication/

The basic code in the view controller for the scene that uses the web view (WebViewController in my code) looks like this:

override func loadView() {
super.loadView()
if GameController.webView == nil {
var webFrame = self.container!.frame
webFrame.origin.x = 0
webFrame.origin.y = 0
let config = WKWebViewConfiguration()
webView = WKWebView(frame: webFrame,
configuration: config)
GameController.webView = webView
} else {
webView = GameController.webView
}
self.container!.addSubview(webView)
}

In my case, I wanted to send information from JavaScript code in the web view to Swift code in my app, so I had to work more with configurations. I also wanted the web view to be transparent, so I added a statement to do that.

override func loadView() {
super.loadView()
if GameController.webView == nil {
var webFrame = self.container!.frame
webFrame.origin.x = 0
webFrame.origin.y = 0
let config = WKWebViewConfiguration()
config.userContentController.add(self, name: "scriptHandler")
webView = WKWebView(frame: webFrame,
configuration: config)
webView.isOpaque = false
GameController.webView = webView
} else {
webView = GameController.webView
webView.configuration.userContentController.removeScriptMessageHandler(
forName: "scriptHandler")
webView.configuration.userContentController.add(self,
name: "scriptHandler")
}
self.container!.addSubview(webView)
}

Originally I only set the script handler when I first made the web view, but that didn't work. Apparently a new view controller object was made each time the scene was loaded, so the old script handler didn't work. This code deletes the script handler that pointed to the old view controller and adds a script handler that points to the new view controller.

WKWebView catch HTTP error codes with Swift 4

Using a WKNavigationDelegate on the WKWebView you can get the status code from the response each time one is received.

func webView(_ webView: WKWebView, decidePolicyFor navigationResponse: WKNavigationResponse,
decisionHandler: @escaping (WKNavigationResponsePolicy) -> Void) {

if let response = navigationResponse.response as? HTTPURLResponse {
if response.statusCode == 401 {
// ...
}
}
decisionHandler(.allow)
}

WKWebView Navigation Delegate Not Called

You need to move let test = TestWebview () to class level, otherwise this object is going to be evicted when viewDidLoad completes: the navigationDelegate is defined as weak, so it's not going to prevent it either.



Related Topics



Leave a reply



Submit