We make software for humans. Custom Mac, Windows, iOS and Android solutions in HyperCard, MetaCard, and RunRev LiveCode
Debugging on mobile platforms isn’t as easy as using the debugger in the IDE but it is possible to get information about things that go wrong if you prepare your stack ahead of time. There are several ways to report errors and script progress. The most-used methods are:
Convenient and easy, but dialogs can interfere with script flow. The answer dialog also changes the values of the “it” variable and “the result” which can cause unexpected results in scripts.
Logging to a field:
Avoids the issue of script interference but requires an additional object in the stack which needs to be removed or hidden later. If the scripts loop through card controls, the extra field gets in the way.
Logging to a file:
A good way to keep a record of events and errors which is workable on Android devices and in the iOS and Android simulators. However, the file system is largely inaccessible on physical iOS devices so log files aren’t a good option there.
Logging to stdout (standard output):
This is one of the best methods. It does not interfere with objects or script execution, and cleanup is simple when debugging is done. On iOS, there is no particular setup required, you only need to launch an app. On Android a terminal command is required, but once set up it works very well.
This document explains how to use the last method. When LiveCode encounters an error, or when the put command is issued without a destination, data is sent to stdout. In the IDE, stdout is redirected to the message box. On iOS, stdout can be viewed using the Console app or XCode. On Android it can be seen in a terminal program.
There are two debugging handlers to add to your stack script, one to log events on demand, and the other to catch runtime errors. Put these where they will always be in the message path, such as in the stack script of the app’s mainstack.
The logging handler is a variation on Andre Garzia’s useful example, and allows flexible logging to a file, stdout, or almost anything by simply changing a constant. It’s been modified here to allow the use of an answer dialog. You could enhance it further to log to a field in the stack.
constant kDebug = "msg" -- change destination here on log pText switch kDebug case "msg" put pText break case "file" put pText & cr after url ("file:" && the effective filename of this stack & ".log") break case "answer" answer pText break end switch end log
The second handler catches any runtime errors that occur and reports them:
on errorDialog pErr log pErr end errorDialog
Whenever you want to track the state of a variable or the progress of a handler, insert a line similar to one these into the script:
log “some message here” -- for example, “openstack now running” log the params log tUserName -- a variable in the handler
When you are done debugging, either comment out the body of the log handler or put empty into the
kDebug constant. Leave the declaration intact (the “on” and “end” lines) so no errors will occur at runtime in case you forget to remove all the “log” debug lines in the scripts.
If you are using the iOS simulator, debugging output can be viewed in the Console app. Console ships with OS X and is located in Applications/Utilities.
Launch Console and select “All messages” at the top of the left-side list. To limit the output to your own app’s data, enter any distinctive part of your app ID into the filter field at the top right of the window. Often this is the name of your company or the name of your app.
If you are debugging on a physical device, launch XCode instead. Under your connected device, click the Console icon. Output can be viewed here.
In LiveCode, click the Test button to start your app. Any logging commands in the script will run as you interact with it.
Start up the Android emulator if it isn’t already running, which automatically launches a terminal application. To debug, open a new terminal window. You can’t use the one that opened the emulator.
The adb utility is used for debugging. It’s located in your Android SDK folder, inside the platform-tools folder. The logcat command starts the logging process. To enter it, provide the full path to the adb app followed by the logcat command, like this:
The easiest way to get the full path is to just drag the adb file into the terminal window. Then type a space and the word logcat.
Android produces a great deal of data, most of which won’t be relevant. You can filter much of the output by adding special tags to the terminal command. To filter for LiveCode output, add these filters (all one line, ignore any wrap):
/android-sdk-macosx/platform-tools/adb logcat revandroid:D LiveCode:I *:S
LiveCode Android apps include two libraries, revandroid and LiveCode. The "D" tag means "debug" and "S" means "silent", so the above command means: report debug data from revandroid, report all info from LiveCode, and mute everything else.
Once you’ve started up logcat, click the Test button in LiveCode to launch your standalone. Terminal will log all output received from either a physical device or the emulator.
To stop logcat, type Control-C.
More info about debugging with adb and using filter tags is available in the Android developer docs at http://developer.android.com/guide/developing/tools/adb.html
Runtime errors are reported as a series of lines comprised of itemized numbers, like this:
241,3,1,mouseUpThe top line in the series is usually the most significant; the lines below it are the history leading up to the error, in reverse order. The numbers in each line indicate:
error code, script line number, character offset, text hint
The text hint may not always be available. In the IDE the error codes (the first number in the line) are deciphered before they’re reported, but in mobile debugging you’ll need to look them up. The User Samples area available from the LiveCode tool bar contains a LiveCode Error Lookup stack which can be placed in your plugins folder for quick access.
Enter either a single error code into the field in the Basic Lookup, or copy all the error lines and paste them into the Multiline Lookup tab of the lookup stack. Pasting all the lines at once lets you see the entire sequence of events that led up to the failure.
The LiveCode Error Lookup stack retrieves its error codes dynamically from the currently running copy of LiveCode, so it will always be up to date.