Passing on optional arguments in ActionScript 3

The other day I ran into a small problem with optional arguments in Flex. While writing my tutorial on AMFPHP and Flex I decided to create a small static class that would take care of all the boring stuff with calling AMFPHP. This class enables me to simply use AMFPHP.send(“ServiceName”, and so on).

However, writing the class I realized I wouldn’t be able to pass on the optional parameters. If I would use:

function send(anArgument:Object, ...args)

…I wouldn’t be able to send the args argument to the NetConnection.call method, because actionscript would send a “bunched up” array with all the arguments as ONE parameter to the call method, as opposed to a series of parameters, which was what I wanted.

The solution to this is using the Function.apply() method. What I did was to create an empty array and add a series of arguments I wanted to pass on to a function, create a reference to the function and then use the apply method. This is what my finished static method looks like:

public static function send(serviceFunction:String, resultHandler:Function, faultHandler:Function, ... args:*) : void
{
	trace("AMFPHP("+serviceFunction+")");
	// Create responder
	var responder:Responder = new Responder(resultHandler, faultHandler);
	// Create an array that will temporarily store all the arguments
	var collectArgs:Array = new Array;
	// Add the fixed arguments
	collectArgs.push(serviceFunction);
	collectArgs.push(responder);
	// Loop through the optional arguments and add them too
	for (var i:uint=0; i

AMFPHP and Flex

Being a LAMP (Linux Apache MySQL PHP) guy as well as a Flex developer it didn’t take me long to discover AMFPHP. If you haven’t heard of it I can tell you in short it’s a framework for sending and receiving data between Actionscript and PHP, without having to use an XML layer or similar in between, so to speak. It’s really neat, because lets say you extract an array of rows from your MySQL database, then you can just pass the entire array back to Actionscript and it will be received as an Actionscript array in the other end.

Would you like to try it? This is how to do it:

1. Download the latest AMFPHP package from www.amfphp.org

2. Unpack and (preferably) place the folder called amfphp in the document root on your web server.

3. By default the AMFPHP gateway is set to converting all UTF-8 data to Latin 1. Big NO NO for “international” developers like me, so you should open the gateway.php file in the amfphp folder for editing and change the following line (it should be around line 127):

$gateway->setCharsetHandler("utf8_decode", "ISO-8859-1", "ISO-8859-1");

to

$gateway->setCharsetHandler("iconv","UTF-8","UTF-8");

If you don’t do this all UTF-8 special characters from the database will be distorted on arriving at the Flex application.

4. Now create a simple PHP class file, call it HelloWorld.php, and place it in the /amfphp/services folder. You should use a commenting pattern like that of PHPDoc. Here is a simple HelloWorld example:

/**
 * A simple amfphp service.
 */
class HelloWorld
{
	/**
	 * A simple HelloWorld function
	 * @returns A string containing the phrase 'Hello World!'
	 */
	function SayHello()
	{
		return "Hello World!";
	}

	/**
	 * A simple HelloWorld function that bounces back the given string
	 * @returns A string containing the supplied string
	 */
	function SayWhat($string)
	{
		return $string;
	}
}

In this class I’ve put two functions; one that returns the string ‘Hello World!’ and another that returns whatever string you send to it. Okay, so let’s get on with the show…

5. Now you can test your service by browsing to the browser folder. It should have a URL similar to this: yourserver.com/amfphp/browser. In the service browser you can test whether your class is working as it should.

6. Flex
To simplify things I’ve created a small class for the implementation of this in Flex. There is a number of ways of doing this, but I’ve chosen the one way that I am most comfortable with.

For ease of use, create an actionscript document in your Flex Projects root directory called AMFPHP.as and past the following code into the file:

package {
	import flash.net.NetConnection;
	import flash.net.Responder;

	public class AMFPHP
	{
		private static var gateway:String = "http://www.yourserver.com/amfphp/gateway.php";
		private static var connection:NetConnection = new NetConnection;
		connection.connect(gateway);

		public function AMFPHP() : void
		{
			// Static class
		}

		public static function send(serviceFunction:String, resultHandler:Function, faultHandler:Function, ... args:*) : void
		{
			trace("AMFPHP("+serviceFunction+")");
			// Create responder
			var responder:Responder = new Responder(resultHandler, faultHandler);
			// Create an array that will temporarily store all the arguments
			var collectArgs:Array = new Array;
			// Add the fixed arguments
			collectArgs.push(serviceFunction);
			collectArgs.push(responder);
			// Loop through the optional arguments and add them too
			for (var i:uint=0; i

The only thing you have to change here is the URL to the gateway.php file on your server at line 7 in the file.

7. Usage

To use this in your code you will need three things:

• Calling the service using the static AMFPHP.send() function
• A function that handles the result coming from amfphp
• A function that handles errors

This is the first HelloWorld example (without the argument). The first argument for the send() function is a string describing the path to the function, with this structure: [directory.]class.function, within the services folder. A directory is not necessary, but can be convenient if you have packages of many classes.

private function helloWorld() : void
{
	AMFPHP.send("HelloWorld.SayHello",onResult,onFault);
}

private function onResult(result:String) : void
{
	trace(result);
}

private function onFault(result:Object) : void
{
	trace(String(result.description));
}

Easy huh!?

And the example with the argument is pretty much the same, but with an argument added to the end of the function call. Like this:

private function helloWorld() : void
{
	AMFPHP.send("HelloWorld.SayWhat", onResult, onFault, "Hello to you!");
}

private function onResult(result:String) : void
{
	trace(result);
}

private function onFault(result:Object) : void
{
	trace(String(result.description));
}

Note that I changed the path to the function from HelloWorld.SayHello to HelloWorld.SayWhat to use the other function in the class.

Well, that's it. Hope it was of some use. Good luck!

I am a dork!

Okay, so yesterday I realized it has nothing to do with updating Tiger for Mobile Me. I could just go on using the .mac service like I always had. The only thing I had to do was open the settings on the iPhone and activate synchronization for the calendar and contacts on the .mac account. It now works fine. I think Apple has been a little evasive regarding this piece of information, don’t you?

Well, it was easy enough when I realized what to do. … tsk… and I call myself a geek…

Mobile Me on Tiger

LATER NOTE: Despair not! There is no problem using Mobile Me on Tiger. Read more here

Is it just me or is there not a Mobile Me update for Mac OS X 10.4 (Tiger)? Everywhere I read it says that an update can be found that will replace the dotmac icon in system preferences with a new Mobile Me icon, but I can’t find any such update. Thus I cannot sync my calendar and contacts with my iPhone without plugging it in and doing it via iTunes.
It works but it annoys me. That was one of the things I was really looking forward to when I was standing in that long dorky line waiting for my iPhone 3G. Being a travelling consultant it has it’s advantages being able to sync the phone while not at the office.

Any news on the progress there would be highly appreciated.

photo

FlashTracer Firefox plugin

Update Jan 24 -09: The Flash Tracer that works with Firefox 3 has to be downloaded from the creator’s own site. The one at Mozilla Addons doesn’t work with 3.x (yet). In the instructions below I have therefore used the link to his own site.

If you’re developing for Flash/Flex the FlashTracer can be quite a nifty plugin. It lets you see the flash player trace output directly in a sidebar in you browser. Outputting debugging info is something I use all the time while developing and I have tried several times to get FlashTracer to work, but haven’t managed, so I usually have a textarea inside my flash/flex project with a custom debug output. I guess I have been too impatient before but today I sat down and read through some posts about it. This is how I eventually got it to work on my Mac:

1. Make sure you’re using the latest Flash Player Debug version. Download it here

2. Install the plugin (of course)

3. Open the FlashTracer sidebar in FireFox. Click the Preferences button.

4. Under the area named “Select output file” click browse and point the plugin to the flashlog.txt file your debug player outputs. In my case (being on a mac) it was here:
/Users/{username}/Library/Preferences/Macromedia/Flash Player/Logs/flashlog.txt

The plugin will ask if you want to replace the file, which is stupid because you will want to read from the file, not write to it, but that’s just how it is. Don’t let it scare’ya.

5. Save/close preferences.

6. Restart FireFox.

That should do it.

Spry framework is great! but…

When I first discovered the Spry Ajax framework by Adobe I was jubilant. It gives my HTML applications a similar functionality to the Flex applications I so love. For those who haven’t yet discovered Spry I can tell you it’s a collection of APIs, tools and widgets that make it easier for you to implement ajax functionality on your web site. Many of the widgets are useless (to me) but in general it’s excellent. You can more or less just associate a set of graphics (like rows in a table) with an array (imported externally or built into the page) and the graphics repeat themselves according to the arrays rows. You have to try it to understand its brilliance.

The downside
The documentation is very thorough, but very badly structured. As an example the API documentation does not include the events that can be “listened to” by observers. One has to browse through the Overview document and make much use of the “find” feature of the browser (thank god I’m using Firefox) to find such things.
Another problem is that it sometimes just don’t work. The framework has a really nifty debugging tool built into it, but sometimes errors don’t fire. Simply nothing happens and that makes me furious! I’ve been trying to solve such a problem all day today, but simply can’t find what’s wrong. Firebug (a must-have tool) tells me my dataset has all the data. If I look through the page’s DOM I can find the object there, with all the data in it, but the {labels} I have used in the code are replaced by… nothing…

I’m tired…

Flex Apache module hell

Yesterday I tried to install the flex sdk apache module on the linux server of one of my clients. Note “tried”.

Problem 1: The Java JRE isn’t super easy to install. Well, actually it is, but you just have to realize how to do it and the information out there is quite misleading. I’m no Linux nerd although I can handle a linux server fairly well. This server was a Debian Etch server, so my hopes were quite high. Apt-get is a good tool. The reason the info was so misleading is that all the articles I could found out there in “space” told me you cannot use apt-get to install the Java run-time because of some Sun legal policy. This is not correct. Since sometime in 2005 you can use apt-get to install Java, however you have to add the non-free repository to the sources.list file. Finally I found out how to do it.

Problem 2: The information in the Flex SDK about the apache module is slight to say the least. It is almost essential to find a third party tutorial on some blog to figure out how to set it up. One thing I hate about Adobe, which could be a result of the multitude of information they’re hosting, is the fact that all pages refer to other pages, and some of those pages refer back to the first page and so on and so forth.

Final problem: So I finally performed a manual install of the Flex SDK for Linux! Wohoo! or… not…
The final step is to restart the Apache server. “Nope. I won’t restart” he said, sneerfully. “You are missing an essential thing called GLIBC_2.4. You need that to be able to run the mod_flex.so! Ha ha!”.

In search of such a thing and why it wasn’t already there I found out that the glibc library only exist up to version 2.3 for Debian.

Conclusion
I can’t use the f*king apache module at all and will have to compile my Flex application locally and upload to the server. Too bad, because that will not be easy giving the fact that I’m not alone in this project. The whole idea behind this new project we’re on was creating an online application we could build together.

If someone out there has made this work and can help me out… PLEASE HELP!

Chears
Daniel