Somewhat lame iOS Cordova debugging tip

This post is more than 2 years old.

A while ago I wrote about iOS Remote Debugging and PhoneGap/Cordova apps. Long story short - it kicks butt and is a great way to debug. (And you can do the same with Android.) There is one small issue though that you may run into and I've got a workaround.

In order to use remote debugging with iOS, you have to run Safari, open the Developer menu, and click on your device or the simulator link.

So far so good - except for one thing. Every time you kill and restart the app, Safari will close the debug window. This is not only annoying, but it also means that any console messages, or errors, that show up before you re-open the window are lost. Android does not have this problem. So what to do if you need to debug the application immediately?

Use an alert.

Yeah, that is really lame, but it also works. Consider the following block.

document.addEventListener("deviceready", init, false);
function init() {
  alert('Lame sauce!');
	console.log('running FS tests');
	window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, onFSSuccess, errorHandler);
}

function errorHandler(e) {
  var msg = '';

  switch (e.code) {
    case FileError.QUOTA_EXCEEDED_ERR:
      msg = 'QUOTA_EXCEEDED_ERR';
      break;
    case FileError.NOT_FOUND_ERR:
      msg = 'NOT_FOUND_ERR';
      break;
    case FileError.SECURITY_ERR:
      msg = 'SECURITY_ERR';
      break;
    case FileError.INVALID_MODIFICATION_ERR:
      msg = 'INVALID_MODIFICATION_ERR';
      break;
    case FileError.INVALID_STATE_ERR:
      msg = 'INVALID_STATE_ERR';
      break;
    default:
      msg = 'Unknown Error';
      break;
  }

  console.log('Error: ' + msg);
}

function onFSSuccess(fs) {
	console.dir(fs);

    var dirReader = fs.root.createReader();

    dirReader.readEntries(gotFiles,errorHandler);	
}

function gotFiles(entries) {
	console.log("gotFiles success, size of entries is "+entries.length);
	for(var i=0,len=entries.length; i<len; i++) {
		//entry objects include: isFile, isDirectory, name, fullPath
		var s = "";
		s+= entries[i].fullPath;
		if (entries[i].isFile) {
			s += " [F]";
		}
		else {
			s += " [D]";
		}
		console.log(s);     
	}
}

I placed an alert inside the init function that I've tied to the deviceready event. On load, the alert will stop everything, let me open the debugger in Safari, and carry on. I could have put it on line one as well, but in my case I needed to debug when the deviceready event fired, not before.

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Ronald Klip posted on 2/18/2014 at 3:06 AM

Thanks, nice one. usually press reload in the debugger window. Either with the reload button in the DOM inspector, or with Cmd-R / Ctrl-R. It reloads index.html and thus the entire app. And you get the early messages.

Comment 2 by Raymond Camden posted on 2/18/2014 at 3:36 AM

Nice - didn't know about that one!

What would be *really* cool is if the debugger; command worked like it does in Chrome/desktop.

Comment 3 by Nadav Greenberg posted on 2/18/2014 at 3:40 AM

In ordernot to change the code (sometimes changing it is not an option) I use:
1. open app
2. open safari dev tools
3. set up breakpoints (e.g. in deviceready callback)
4. in dev tools console do: window.location.reload()

Comment 4 by Raymond Camden posted on 2/18/2014 at 3:45 AM

Isn't that the same as the first suggestion - just done via code instead of key combo? But yeah - good idea too. :)

Comment 5 by Ivano Malavolta posted on 2/18/2014 at 4:34 PM

weird as hell, but TREMENDOUSLY useful :)

Comment 6 by Todd Hensley posted on 2/21/2014 at 12:43 AM

I can't get this to work on a physical phone. Safari pages show up, but not PhoneGap apps. It it supposed to work on an actual device, or only the simulator? I'm running Safari 7.0.1 on the Mac and iOS 7.0.4 on an iPhone 5.

Comment 7 by Raymond Camden posted on 2/21/2014 at 12:47 AM

Yes, it is supposed to - but did you enable it on the phone? You were supposed to. (I talk about it on the article I link to towards the beginning of the article.)

Comment 8 by Todd Hensley posted on 2/21/2014 at 1:05 AM

Yes, I believe I have the phone and Safari on the Mac set up properly, because I can see Safari pages. PhoneGap apps are not showing up.

Comment 9 by Raymond Camden posted on 2/21/2014 at 1:33 AM

I tested with a 3.4 project (brand new), and it works.

Comment 10 by Dan Baker posted on 3/1/2014 at 12:33 AM

Ive had some success using weinre, its a javascript debugging tool which you inject into the page.

Comment 11 by Raymond Camden posted on 3/1/2014 at 12:41 AM

Weinre is pretty darn good, yep.

Comment 12 by Simon Shepherd posted on 3/24/2014 at 3:55 PM

Hey guys.

If you hit cmd+R while focused on the safari inspector, the app will reload on the device/simulator. This is what I use and it works for 99% of cases (except for first install processes).

Thanks

Simon

Comment 13 by Brad Wedell posted on 5/21/2014 at 5:19 AM

If you're using a mac, you can use this gist to create a .app file in automator - gist.github.com/bwdolphin/e... . Then, in terminal (assuming you launch with command line), create a bash alias to call the cordova build command and then launch that app (which has a 1.5 second delay to give the app time to launch on the device before trying to open the console). To polish it off, you can do what the author suggests and add a timeout to your init script (longer than the 1.5 seconds you already wait for the app to load), and voila, you have an app that launches the debug console everytime you build!

Comment 14 by Raymond Camden posted on 5/21/2014 at 5:29 AM

Ok, that's kinda slick! Thanks for sharing it.

Comment 15 by Maslow posted on 1/31/2016 at 10:57 AM

Sir, I love you.

Comment 16 (In reply to #3) by Maslow posted on 1/31/2016 at 10:59 AM

Well the reload sometimes doesn't work. Sadly. The alert() tips seems to work everytime