While I've been a developer for many years, my immersion into mobile development is relatively new compared to the rest of my endeavors. I love the opportunities to try out new languages, technology stacks and platforms - but one of the most challenging things you encounter as you embark into this kind of 'unknown territory' is mastering the tools available to give you accurate and early feedback as to the state of your application code as it runs. Desktop browser tooling has leapt forward light years in this department. I've seen some truly impressive debugging and runtime 'visibility' features in every browser, especially Chrome and Firefox.
The state of things on the mobile side, however, is a different story.
This is, perhaps, the primary reason why developers writing hybrid mobile applications do as much debugging of their app as possible in a desktop browser - with Cordova shims in place. With powerful capabilities to inspect the DOM, profile your application, set breakpoints, and get the advantage of testing changes to your code by hitting refresh (or if you're using a LiveReload style setup, not even needing to refresh) - how could you not take advantage of these tools?
And most of the time, these tools are indispensable and cover nearly all your needs.
But not all of them.
Testing a hybrid mobile app in a Cordova-emulating desktop browser is no substitute for actually running your app on multiple devices. Not only that, testing your hybrid app in a browser isn't even an option if you're using custom Cordova plugins (unless you've shimmed them to prevent errors – and even then, it's no substitute).
So, what's a developer to do?!
You do have a few options – and like the Beatles said, it's getting a little better all the time. For the purposes of this post, we're going to focus on one option that is a great mixture of being easy to set up as well as covering both Android and iOS: weinre.
Remote Debugging via Weinre
Weinre (pronounced by most as "winery"), stands for Web Inspector Remote. It's a fantastic tool allowing you to remotely inspect and debug web apps - including those running on a mobile device.
In order to get set up to use weinre locally, you need to install node.js. Assuming you have node installed, open up a terminal/command prompt and enter the following to install weinre:
npm install -g weinre
Once installed, it's worth checking out the commands available when working with weinre (you can do this by typing
weinre --help in your terminal):
You can read more about the options here. We only need to worry about the
boundHost option for now.
To start, you just need the IP address of the machine you plan to run weinre from. In my case, I need the IP my Macbook Pro is using on my wireless network:
Now that I know my IP address, I can start weinre, passing my IP address as the
weinre --boundHost 10.0.1.3
You'll notice that the console output indicates a server at
http://10.0.1.3:8080 - if we browse to that location, we'll see something like this:
A key thing to notice is that we have two urls listed under "Targets". This is because I currently have a Nexus 7 and an iPhone5 connected to this instance of weinre - but how did I manage that?
Getting a client to connect is as simple as dropping a script tag into your hybrid mobile app. In this case, I put the following at the end of my index.html's body tag:
The host and port used in the script tag's
src attribute should match the
boundHost value from when you started weinre.
As long as the clients running your application are on the same network as the computer running weinre, when they connect, you will see them listed under "Targets".
Remotely Debugging a Client
To debug a client, simply click on the target you wish to debug to select it. In the screenshot below, I've selected my iPhone 5, the target with the IP address of 10.0.1.4.
Once you've selected a client to debug, just use the menu at the top. If you've used the developer tools in browsers like Chrome, Safari, Opera, etc., then these will look familiar:
To give you a sneak peek, here are a few screen shots of what each panel looks like as you're inspecting an app:
This allows you to inspect the DOM, and as you highlight nodes in the inspector, you will see the elements highlighted/selected in the target device's DOM as well. You can edit nodes, and see the changes reflected in real time.
The Resources pane allows you to inspect client storage (local storage, session storage and client side databases).
Just like you're probably used to in browsers like Chrome, the network panel gives you visibility into the communications occurring between the client and remote endpoints.
It's not quite as full-featured as the timeline you'll see in Chrome's devtools, but this allows you to record an event timeline - giving you a decent start in profiling your app. You'll get more mileage out of Chrome's devtools for profiling memory usage, but this is still very helpful.
Seeing it in Action
I recorded a quick screen capture of running weinre to debug both a Nexus 7 and an iPhone 5. I zoomed in a lot to enlarge the fonts, so it's kind of painful to view the markup inspection at that zoom level, but this should give you an idea of what's possible.
Weinre is definitely not the only option out there, of course. I plan to explore other options – like iOS 6+ support for remote debugging in Safari, jsHybugger and more – in later posts.