A WKWebView
is a great tool for integrating the web into iOS and macOS apps. Often debugging the webpage running inside a WKWebView
can be challenging. This post presents two methods for getting error messages from a WKWebView
:
- Capture Javascript Errors From A
WKWebView
Using Message Handlers - Capture Javascript Errors From A
WKWebView
Using The Safari Web Inspector
Enable Javascript For A WKWebView
Capturing Javascript messages requires Javascript to be enabled on the WKWebView
configuration. You can ensure Javascript is enabled using:
webKitView?.configuration.preferences.javaScriptEnabled = true
Capture Javascript Errors From A WKWebView Using Message Handlers
One method to capture Javascript errors from a WKWebView
uses WKScriptMessageHandler
and WKUserContentController
. First, create a WKScriptMessageHandler
by calling the add(_:, name:)
method on the WKWebView.userControllerController
:
// Create a WKScriptMessageHandler named "error"
let controller = webKitView?.configuration.userContentController
controller?.add(self, name: "error")
Next, to handle message sent by a WKScriptMessageHandler
adhere to the WKScriptMessageHandler
protocol and implement the userContentController(_: didReceive:)
method:
extension ViewController: WKScriptMessageHandler {
// Called for messages received by
// WKWebView message handlers
func userContentController(
_ userContentController: WKUserContentController,
didReceive message: WKScriptMessage) {
// The WKScriptMessageHandler name
// of the sender is message.name
if message.name == "error" {
// Parse the response object to obtain the error
let body = message.body as? [String: Any]
let error = body?["message"] as? String
print(error)
}
}
}
Inside of your web application, you can post messages to WebKit message handlers using the window.webkit.messageHandlers
object. Since a WKScriptMessageHandler
was created called "error", use window.webkit.messageHandlers.error.postMessage
to send messages.
To test the implementation, inject a WKUserScript
when the document starts that calls postMessage
with a message object:
// Create a WKUserScript
let errorScript = WKUserScript(
source:
"""
window.webkit.messageHandlers.error.postMessage({
message: "An error occurred."
});
""",
injectionTime: .atDocumentStart,
forMainFrameOnly: true
)
// Add errorScript to the WKWebView by calling
// userControllerController.addUserScript
let controller = webKitView?.configuration.userContentController
controller?.addUserScript(errorScript)
WKWebView Error Messages Only Contain “Script Error.”
WKScriptMessageHandler
is best suited for web applications that you develop. Calling window.webkit.messageHandlers.error.postMessage
inside of the window.onerror
callback will return detailed error objects only for scripts loaded by the origin, not injected WKUserScript
scripts.
If you try to inject a WKUserScript with a window.onerror callback using message handlers, all errors will return only “Script Error”. The reason is web page security, as described on developer.mozilla.org:
When an error occurs in a script, loaded from a different origin, the details of the error are not reported to prevent leaking information (see bug 363897). Instead the error reported is simply "Script error."
Capture Javascript Errors From A WKWebView Using The Safari Web Inspector
The Safari Web Inspector is the best choice to debug WKWebView
error messages for webpages that you do not control. Follow these steps to open the Safari Web Inspector during app development:
1. Run your application on your iPhone, iPhone Simulator, iPad, iPad Simulator, or Mac. If using an iPhone or iPad, make sure the device is connected to your computer and recognized as a development device.
2. Open Safari Preferences and ensure "Show Develop menu in menu bar" is enabled
- In the develop menu select the
WKWebView
inside of the application you want to inspect
4. Look at the Safari Web Inspector console to find more information about the errors that occurred on the loaded web page
Get Javascript Errors From WKWebView on iOS and macOS in Swift
That’s it! Using WKScriptMessageHandler
and the Safari Web Inspector you are well equipped to debug Javascripts errors that occur in WKWebView
pages.