NilsH
NilsH

Reputation: 13821

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.

Upvotes: 5

Views: 6817

Answers (2)

NilsH
NilsH

Reputation: 13821

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.

Upvotes: 3

jonathanpeppers
jonathanpeppers

Reputation: 26505

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.

Upvotes: 1

Related Questions