Debugging an Open Social application built with Adobe Flex
During my last work week of this year, I got involved in a fun little project where an OpenSocial Widget is developed. This particular widget is targeted at the Dutch Hyves communities. Hyves supports the OpenSocial standard version 0.7.
The widget itself mostly consists of an Adobe Flex 3 application that is embedded in an OpenSocial container using a flash-javascript bridge. The Flex application makes asynchronous calls to the OpenSocial API of Hyves through the javascript bridge.
Hyves users can add this widget to their profile and configure it to point to a charity activity that is initiated by this user. Friends of that user that donate money to support that charity activity are also displayed by the widget, including the total amount of funding that was donated.
All in all a very nice use case for a social application.
The widget was, of course, developed in very little time (remember this is charity...). The code looks awful, but that is okay, because maintenance isn't an issue. It is disposable software. However, because of the extremely pragmatic approach, some nasty bugs creeped in for which I could really use some sort of debugging mechanism. I needed to be able to look inside during runtime.
Fortunately, Hyves provides a sandbox environment that simulates embedding in a real environment. This is where you can test drive widgets that you develop. Of course, I could run and debug the flex application locally, but accessing the OpenSocial API is then meaningless, because you are outside the Hyves context. And, sure, I could possibly produce a debug version of the widget, embed it in the sandbox and connect the Flex Debugger to the application once it runs in the container, but I somehow couldn't get that to work.
That's why I desparately decided to build a mini log console. Since I see no point in keeping that to myself or my employer, I am sharing that thingy with you. It came in really useful to me. I could look under the hood while the app was running and see what was wrong. Purpose fulfilled.
The picture below shows the logger in action:
The mini logger consists of two parts:
- Logger.as
- LoggerPanel.mxml
LoggerPanel.mxml displays the contents of Logger.instance.logText, and provides a clear button.
Below I have attempted to display the source code for all this in a somewhat decent fashion. I couldn't get the layout like I wanted it. I hope you will forgive me for that.
Here's the source code for Logger.as:
package components.logger
{
public class Logger
{
[Bindable]public var logText:String = "";
public function clear(): void {
logText = "";
}
public function logMessage(message:String): void {
var now:Date = new Date();
var timestamp:String = "["
+ now.getFullYear() + "/" + now.getMonth() + "/" + now.getDay() + " "
+ now.getHours() + ":" + now.getMinutes() + ":" + now.getSeconds()
+ ":" + now.getMilliseconds() + "] ";
var newText:String = logText + timestamp + message + "\r";
logText = newText;
}
private static var _instance:Logger = null;
public static function get instance(): Logger {
if (_instance == null) {
_instance = new Logger();
}
return _instance;
}
public function Logger() {
}
}
}
Here's the source code for LoggerPanel.mxml:
<?xml version="1.0" encoding="utf-8"?>
<mx:VBox xmlns:mx="http://www.adobe.com/2006/mxml"
width="400" height="300" alpha="0.95" initialize="init();">
<mx:Script>
<![CDATA[< logger =" Logger.instance;" id="console" height="100%" width="100%" text="{logger.logText}" label="clear" click="logger.clear()" height="20">
Here's how you use it in your code:
<mx:application mx="http://www.adobe.com/2006/mxml" logger="components.logger.*">
<mx:script>
<!--[CDATA[ import components.logger.Logger; function doSomething(): void { Logger.instance.logMessage("I got here"); } ]]-->
</mx:script>
<!-- ... your components... -->
<!-- Embedding the LoggerPanel. You will need to tweak the position and size for ypour application: -->
<logger:loggerpanel visible="{loggerVisible}" id="logger" top="0" left="0" height="350" width="100%">
<mx:button height="20" top="330" right="0" label="{loggerVisible ? 'hide debug log' : 'show debug log'}" click="toggleLogger();">
<!-- End of LoggerPanel embedding -->
</mx:button></logger:loggerpanel></mx:application>
Use it to your advantage.