JavaScript Console Log from a UIWebView

Debugging JavaScript from a UIWebView can be difficult. Generally speaking, take the following approach to debug your HTML and JavaScript code:

  1. First, try debugging using a desktop browser if that is possible. Most modern browsers have very good built in debugger. Also, console.log() method will work there.
  2. If desktop browser can not be used to track the problem down, try running the app in the iOS simulator. Safari can display the output from console.log() occurring within the simulator. Launch the app in the simulator from Xcode. Then, launch Safari and choose Develop > iPhone Simulator > about:blank.
  3. If you can not reproduce the problem in iPhone simulator, then your life becomes difficult since output from console.log() becomes impossible to capture when the app is running an an actual iOS device. But, all is not lost. In this article, I will suggest a way to perform logging from JavaScript that will be captured as application log. Application log can be viewed from Xcode when you run the app on the device from Xcode. The log can also be sent to you by the testers.

Capturing JavaScript Log as Application Log

The basic approach is this. To perform logging from JavaScript, we issue a XMLHttpRequest for the debugger:// protocol and set the log message as the path of the request. We can intercept all HTTP requests from a UIWebView using a¬†NSURLProtocol object. If the request has a “debugger” protocol, the NSURLProtocol object logs the path using NSLog.

Let’s say that you have a file called Sample.html in your project.

function log(msg) {
  var xhr = new XMLHttpRequest();'GET', "http://debugger/" +

function test() {
  log("Button was clicked");
  log("We are done");

  return false;

<button onclick="return test();">Click Me</button>


Next, create a class that extends NSURLProtocol class. We will call the class WebConsole.

@interface WebConsole : NSURLProtocol
+ (void) enable;

@implementation WebConsole
+ (void) enable {
  [NSURLProtocol registerClass:[WebConsole class]];

+ (BOOL) canInitWithRequest:(NSURLRequest *)request {
  if ([[[request URL] host] isEqualToString:@"debugger"]){
    NSLog(@"%@", [[[request URL] path] substringFromIndex: 1]);

  return FALSE;

Basically, the canInitWithRequest callback method checks the protocol of the request. If it is “debugger” then it extracts the path and logs it with NSLog().

Now, from the view controller that contains the UIWebView, enable the WebConsole class.

- (void)viewDidLoad {
  [super viewDidLoad];

  [WebConsole enable];

  NSError *error = nil;
  NSString *htmlStr = [NSString stringWithContentsOfFile:
    [[NSBundle mainBundle]
      pathForResource:@"Sample" ofType:@"html"]

  [self.webView loadHTMLString:htmlStr baseURL:nil];

Now, you can do logging from JavaScript. All log messages will be eventually logged by NSLog.

2 thoughts on “JavaScript Console Log from a UIWebView

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s