Drainbamage.nl blog of Christiaan Ottow

23Jul/091

Pinta – AMF debugger

I'm working on an AIR project that uses an AMF-service to get its data from. Writing such a service isn't difficult, but testing the AMF service functions isn't very straightforward. The way to do so now is to partially implement the client, and make it spit out debugging info. For this project however, since it relies heavily on AMF and there is no client-side app yet, I decided to write a debugging utility for it. It's called Pinta.

I suggested to the commissioner of the project (Axis.fm) that we release the tool under GNU/GPL, and they agreed. So, the tool can be found now on http://code.google.com/p/pinta.

What the tool does: it allows the user to connect to an AMF service and make calls, and prints out the results in text and tree forms. So basically, it's a generic AMF client. Since AMF has no service discovery methods, the user needs to define what services are available on the server. When the AMFPHP browser, that comes with a default install, is present on the server, Pinta can use it do discover the available services for you.

In the future, the plan is to build unit testing support into Pinta, so that with one click you can see if your AMF service still responds as it should.

More info about the tool can be found on the Google Code page, http://code.google.com/p/pinta. I hope the tool is useful to some, feel free to comment/request features/report issues.

Post to Twitter Tweet This Post

17Jul/091

AS3 object serialization pitfalls

I'm working on an AIR project now, and I wanted to save some user data locally. There are a few ways to do so, including SQLite, LSO, and plain file writing in the local datastore.
I wanted to save an ArrayCollection containing connection profiles the user specified, and SQLite seemed like a bit of an overkill for this. Coming from a Java background, I just wanted to serialize and save my ArrayCollection so I wouldn't have to reconstruct it from SQL every time.

Fortunately, this is possible with ActionScript 3, using the FileStream class's readObject() and writeObject() methods. Here's the code I used to read and write the profiles:

private function loadProfiles():void
{
	var prefsFile:File = File.applicationStorageDirectory.resolvePath(fileName);
	var fs:FileStream = new FileStream();
	if( !prefsFile.exists )
	{
		profiles = new ArrayCollection();
	} else {
		try {
			fs.open( prefsFile, FileMode.READ );
			profiles = fs.readObject() as ArrayCollection;
			fs.close();
		} catch( e:Error ) {
			Alert.show( "Error while loading profiles: "+e.message, "Load error");
		}
	}
}

public function saveProfiles():void
{
	var prefsFile:File = File.applicationStorageDirectory.resolvePath(fileName);
	var fs:FileStream = new FileStream();
	try {
		fs.open( prefsFile, FileMode.WRITE );
		fs.writeObject(profiles);
		fs.close();
	} catch( e:Error ) {
		Alert.show("Failed to save profiles: "+e.message, "Save error");
	}
}

There are a few pitfalls however when loading the profiles. First, the player must be able to tell the class of the objects it is loading. For some reason, it cannot do so unless you specify it explicitly:

package nl.aboutcoding.servicebrowser.model
{
	import mx.collections.ArrayCollection;

	[RemoteClass(alias="nl.aboutcoding.servicebrowser.model.Profile")]
	public class Profile
	{

Secondly, the class MUST have a constructor, otherwise the objects are typed as Object and type casting will fail with a message concernin "Type coercion failed". I often skip the constructor on ValueObjects, and it took some time to figure out.

Post to Twitter Tweet This Post

   

Twitter links powered by Tweet This v1.7, a WordPress plugin for Twitter.