Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Capturing console.log within a UIWebView

I'm writing an iOS application with MonoTouch that does some javascript interaction with a UIWebView. For debugging purposes, it would be nice to be able to "capture" console.log in the javascript that runs in the UIWebView together with the rest of the application output. Is this possible? Examples using regular Objective-C code is also OK.

like image 770
NilsH Avatar asked Oct 05 '22 14:10

NilsH


2 Answers

After some more googling, I came about this answer: Javascript console.log() in an iOS UIWebView

Converting it to MonoTouch yields this solution:

using System;
using System.Web;
using System.Json;
using MonoTouch.UIKit;

namespace View
{
    public class JsBridgeWebView : UIWebView
    {

        public object BridgeDelegate {get;set;}

        private const string BRIDGE_JS = @"
            function invokeNative(functionName, args) {
                var iframe = document.createElement('IFRAME');
                iframe.setAttribute('src', 'jsbridge://' + functionName + '#' + JSON.stringify(args));
                document.documentElement.appendChild(iframe);
                iframe.parentNode.removeChild(iframe);
                iframe = null;  
            }

            var console = {
                log: function(msg) {
                    invokeNative('Log', [msg]);
                }
            };  
        ";

        public JsBridgeWebView ()
        {
            ShouldStartLoad += LoadHandler;
            LoadFinished += (sender, e) => {
                EvaluateJavascript(BRIDGE_JS);
            };
        }

        public bool LoadHandler (UIWebView webView, MonoTouch.Foundation.NSUrlRequest request, UIWebViewNavigationType navigationType)
        {
            var url = request.Url;
            if(url.Scheme.Equals("jsbridge")) {
                var func = url.Host;
                if(func.Equals("Log")) {
                    // console.log
                    var args = JsonObject.Parse(HttpUtility.UrlDecode(url.Fragment));
                    var msg = (string)args[0];
                    Console.WriteLine(msg);
                    return false;
                }
                return true;
            }
        }   
    }
}

Now all console.log statements in javascript in a UIWebView will be sent to Console.WriteLine. This could of course be extended to any kind of output one would want.

like image 168
NilsH Avatar answered Oct 13 '22 09:10

NilsH


Can you add javascript code that does something like this to overwrite the method:

console.log = function(var text) {
    consoleforios += text;
}

Then from the web view, call:

string console = webView.EvaluatingJavaScript("return consoleforios;");

This might not be something I'd leave in permanently, but it should work.

like image 26
jonathanpeppers Avatar answered Oct 13 '22 09:10

jonathanpeppers