Search code examples
javascriptswiftuiwebviewconsole.log

Javascript console log in UIWebView in Swift


Is there any way to print logs that is created by "console.log" in web page in UIWebView or WKWebView in swift (like Chrome F12.)

Have a nice days.


Solution

  • Here's a basic implementation for the UIWebView:

    import UIKit
    
    class ViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            // Create the web view.
            let webView = UIWebView()
            webView.translatesAutoresizingMaskIntoConstraints = false
            view.addSubview(webView)
            webView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
            webView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
            webView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
            webView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
            webView.delegate = self
            webView.loadRequest(URLRequest(url: URL(string: "https://www.google.com.py")!))
        }
    }
    
    extension ViewController: UIWebViewDelegate {
        func webViewDidFinishLoad(_ webView: UIWebView) {
            let js = "console.log = function() {window.location = 'logger://webview?' + JSON.stringify(Array.prototype.slice.call(arguments))}"
            webView.stringByEvaluatingJavaScript(from: js)
        }
    
        func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
            if request.url?.scheme == "logger" {
                guard let data = request.url?.query?.removingPercentEncoding?.data(using: .utf8) else { return true }
                guard let obj = try? JSONSerialization.jsonObject(with: data, options: []) else { return true }
                guard let jsonData = try? JSONSerialization.data(withJSONObject: obj, options: .prettyPrinted) else { return true }
                guard let json = String(data: jsonData, encoding: .utf8) else { return true }
                print(json)
            }
            return true
        }
    }
    

    Example

    console.log(4, 3.53, 'Hello', {d: {f: 4}}, function() {}, undefined, null, true)
    

    Prints the following in Xcode log:

    [
      4,
      3.5299999999999998,
      "Hello",
      {
        "d" : {
          "f" : 4
        }
      },
      null,
      null,
      null,
      true
    ]
    

    Caveats

    • This only prints logs executed after the page has loaded.
    • Since we're using JSON.stringify, we can't print the following types: function, undefined
    • Since we're using JSON.stringify, true and false are printed as 1 and 0, respectively