Debugging Tabris.js app’s JavaScript code on iOS devices

The essential part of the development is debugging. Debugging JavaScript code on iOS devices is possible and quite easy. However, it has to be performed in Safari, and that is why a Mac machine is required.

Prerequirements

To start debugging, you have to enable Develop menu in Safari’s settings. To do so, open preferences pane in Safari (or press Cmd + ,) and go to Advanced tab. There, you have to check Show Develop menu in menu bar. This will make developer tools visible to you. Next, you connect your device to your Mac using cable or have it connected to the same network as your Mac (if you have enabled wireless debugging in Xcode). Alternatively, you start a simulator you want to test with from Xcode. They should show up just below User Agent in the Develop menu. If you don’t see them, please restart Safari.

In Develop menu choose your device and select Use for development.

Following this, you will have to approve the request to trust your computer.

You also have to prepare an iOS device or simulator. First, open Settings app, go to Safari, and then to Advanced menu. In there, you have to enable Web Inspector option.

Debugging

To showcase the debugging process, I will use actionsheet.jsx snippet. While it is not a pure JavaScript snippet, it is still simple enough to be a good example even after it is compiled. To start debugging, you have to select JSContext of your app that is available on your device. It means that the app needs to be running.

After selecting JSContext, Web Inspector will show.

On the left of the window, there is a list of JavaScript source files already loaded into the virtual machine. Above it, you can find controls that allow you to disable all breakpoints, pause/continue execution, step over, step into, and step out.

Let’s select actionsheet.js. In the center, you can see the source code in the selected file. You can place a breakpoint by clicking on a number line, like in most debuggers. At the bottom of the window, you execute JavaScript code. Let’s start by placing a breakpoint on line 16. This way, the debugger will stop when the button is pressed.

On the right side of the window, all local properties are listed. To access a button, we need to get a reference on. We can do this by using cid property and find() method.

The result of every operation is saved in a temporary variable; in this case, it’s $1. find()and it returns an array of widgets that meet the condition. In our case, it will only be one widget. We can save it under a new variable by executing the following line:

Let’s change this button’s text.


Pausing app execution on app start

In some scenarios, you might want to pause the execution as soon as the app starts. Because iOS JavaScript virtual machine lazily loads all the source files, therefore they will appear in Web Inspector only after they are used. Due to this, you have to run the app once, place breakpoints, and quit your app. Quitting your app will cause Web Inspector to close, but do not worry as Safari will remember where you have placed your breakpoints. Let’s clear all the existing breakpoints and place a new one on line 11. Before starting the app again, there is one more option we need to check. It is called Automatically show Web Inspector for JSContexts.

If this option is unchecked, the debugger will not stop at the breakpoint we have just placed. We can start the app now and… it stops exactly where we placed the breakpoint. From this point on, you can inspect and debug your app in whatever capacity you need.

Second checkbox

As you’ve probably noticed, there is a second checkbox called Automatically Pause Connecting to JSContexts. I rarely use this option as it pauses your app’s execution as soon as Web Inspector is opened (automatically or manually). This may result in an application being paused in an unpredictable state. However, if you use this option in conjunction with Automatically show Web Inspector for JSContexts, it will pause execution on the first line of the first file that is being loaded into the JavaScript virtual machine. In practice, this means that it will stop as soon as boot.js starts its execution. You can start from this point, but you will have to do a lot of steps to get into your source file. I almost never use this method of pausing the app execution on the app start since it’s way too early in the app’s lifecycle to be useful.

Summary

While JavaScript debugging on iOS requires more involvement and setup than on Android, I find JavaScript debugging tools in Safari robust enough to help me during the app development process. The two biggest challenges though, are Mac requirement and general lack of resources about this feature (or at least I haven’t found them). It’s a shame because these debugging tools in Safari are critical in finding and fixing problems in your app. Hopefully, it will start to change.