Heads up: SWX Beta 1 on Wednesday this week

Yep, you heard right: Beta 1. No more Alphas! I'm skipping Alpha 0.3 and going directly to Beta 1.

SWX has been progressing faster than I imagined and I feel it's now ready for Beta.

What does that mean? Well, it means that it's pretty much feature complete and the API, which will be introduced in Beta 1, shouldn't change dramatically. This doesn't mean that it won't change at all during the beta process and that new features won't be added, it just means that I will make a greater effort to make sure that existing applications do not break.

Also, during the Beta process I will be concentrating very heavily on creating documentation, tutorials, screencasts, etc. In short, everything and anything to make sure that SWX is easy as pie to get up and running with.

I am also almost ready with the SWX MAMP Bundle, which will allow developers on OS X a simple three-step process for getting started with SWX:

The SWX Start Page appears automatically once the server has started and you have a full development server with Apache, PHP, etc. and SWX installed and running.

I will most likely release the SWX MAMP Bundle a little after the release of SWX Beta 1. Perhaps the same day, perhaps a day later (I'm also in the throes of moving house this week so I might not be able to manage a simultaneous release of both components -- or maybe I will!) Regardless, they'll both be released this week.

The biggest new feature in this release will be the new SWX API and library. Still very lightweight, the SWX API makes it easy to build data-driven applications without having to worry about the lower level details of the data exchange. Don't get me wrong, it's still very important that you understand these details (and they are so simple to understand in SWX that you actually can understand them without a degree in rocket science).

With this release, you will have three ways of using SWX.

First, you can use SWX without the API at all. That's right, you can use SWX without importing a single class or a single line of library code. SWX is native, remember. All you need is loadMovie(). (Man, that would make a great t-shirt!)

Here's a simple example that does not use the SWX API at all:

Note: As of beta one, the arguments property will become args. See this post for more information on this change.

// dataHolder is a movie clip on the stage.
dataHolder.serviceClass = "Twitter";
dataHolder.method = "getNumFriendsUpdates";
dataHolder.args = '["aral", 5]';
dataHolder.debug = true;

dataHolder.loadMovie("http://swxformat.org/php/swx.php", "POST");

That's all there is to it!

The code above calls the getNumFriendsUpdates() method in the SWX Twitter API (the Twitter class in PHP) and passes it the string "aral" as the first argument and the number 5 as the second argument.

In other words, there is a class (in the php/services folder) of swxformat.org that has a method that looks something like this:

class Twitter
{
    function getNumFriendsUpdates($userName, $n = 20, $since = NULL)
    {
        // Calls the official Twitter API and gets a list of friends
        // ...
    }

And you use the above code in ActionScript to call that method and have the results returned to Flash. The results are returned in a SWX SWF file, as native Flash objects that you can start using right away without having to deserialize them.

(You can test the methods in your service classes online, without writing any Flash code, by using the PHP Service Browser in SWX. Try it now!)

Notice how you have to encode your arguments in JSON format yourself. Although this is simple enough for simple arguments as in this sample, you probably won't want to do this when passing more complicated arguments.

Notice also that you the code sample here isn't checking for the result.

You can see the result in the SWX Analyzer since debug mode is on but you will want to check that the data has loaded and do something with it in your application also. The simplest way to do this is to use setInterval() to check getBytesLoaded() and getBytesTotal() on the dataHolder movie clip at regular intervals. Once the data has loaded, dataHolder.result will contain the loaded data (in this case, my last five friends' updates) in a regular ActionScript array.

To access the text of the first update, for example, you would reference it as dataHolder.result[0].text.

This example shows you how native SWX truly is. You can use it without any libraries or classes. It also means that you can easily build your own APIs on top of SWX or incorporate SWX into your existing frameworks very easily. By reading this example, you already know how SWX works. That's all there is to it! Yes, it's actually that simple!

The big disadvantage to not using the SWX API at all is that you have to manually serialize your arguments in JSON format. That's doable when your arguments are simple, as in this example, but not so if you wanted to send, say, a large array of objects. In this case, you can use the second method that's available: The minimal SWX API.

Here's how the same code would look using the minimal SWX API:

import org.swxformat.SWX;

// dataHolder is a movie clip on stage.
dataHolder.serviceClass = "Twitter";
dataHolder.method = "getNumFriendsUpdates";
dataHolder.args = ["aral", 5];
dataHolder.debug = true;

SWX.prepare(dataHolder);

dataHolder.loadMovie("http://swxformat.org/php/swx.php", "POST");

There are three differences here:

So that's all it means to use the minimal SWX API. Basically, you're just importing the SWX class to use a single method: the prepare() method which serializes your arguments into JSON format for you.

You still have to check for load progress, however. Also, if you're building a Flash Lite application, you have to make sure that you queue your loadMovie requests so that only one loadMovie is happening at once so that you don't choke the device that it's running on (some devices actually cannot handle more than one loadMovie call per frame and nearly all of them will choke on multiple loadMovies). It's a good idea to queue your loadMovie calls in any case, even for desktop applications, as the HTTP 1.1 spec limits you to two successive downloads in any case.

So that's a lot of code you have to write to manage the download of the SWX SWFs. Well, it would be, if it wasn't for the new SWX API (taadaa!)

I will, of course, be writing at length about the new API and documenting it with the release of the Beta but here's a heads up.

The SWX API helps you by proving the following functionality:

Here's the same sample application but using the full SWX API this time and with the handler methods for the various events:

import org.osflash.SWX;

// Create the SWX object.
swx = new SWX();
swx.gateway = "http://swxformat.org/php/swx.php";
swx.encoding = "POST";
swx.debug = true;

// And the method parameters object.
var methodParameters:Object =
{
  serviceClass: "Twitter",
  method: "getNumFriendsUpdates",
  args: ["aral", 1],
  progress: [this, progressHandler],
  result: [this, resultHandler],
  timeout: [this, timeoutHandler]
}

// Make a SWX call.
swx.call(methodParameters);

//
// Event handlers
//

function progressHandler(event:Object)
{
  trace (event.bytesLoaded + " of " + event.bytesTotal + " loaded...");
}

function resultHandler(event:Object)
{
  trace ("The first update is " + event.result[0].text);
}

function timeoutHandler(event:Object)
{
  trace ("The data call timed out for loader: " + event.target);
}

The full SWX API definitely makes things easier. For starters, you can specify callbacks for progress, result and timeout. And, behind the scenes, SWX manages the queuing of calls for you.

Notice how you are no longer working directly with movie clips and loadMovie(). Instead, you create a SWX object and set the gateway, encoding type (GET or POST) and other properties there. Then, you create a separate methodParameters object that contains the details of the method call you want to make to the server side.

In the methodParameters object you specify the server-side service class you want to instantiate, the method on that instance that you want to call and the arguments you want to pass to that method. You also specify any event handlers that you want to use.

Notice how you set the event handlers in the methodParameters object: Each handler is defined in an array where the first element is a reference to the scope of the event handler method (the object that the function is attached to) and the second element is a reference to the function itself. This is necessary since we don't have what is known as "method closures" in ActionScript 2 (we do in ActionScript 3, but that's another story). What this means is that unless you tell SWX where your event handler lives, it will have the incorrect scope when it gets called. You may have heard of a class called Delegate that is used as a workaround in these situations. I decided not to force you to use the Delegate class as I find that the array notation is easier to use (you don't have to import yet another class and there's less code.)

If you are building Flash Lite applications with SWX (and many of you will be since it's the best solution for creating data-driven applications with Flash Lite), make sure you use the new API. Also, if you're interested in digging deeper, that a look at the LoadManager and ExternalAsset classes that come with it as they will be useful to you if you have to load other external assets (JPEG, SWF files, etc.) in your Flash Lite applications. There is also a handy FrameLoop class in there that you'll need in Flash Lite.

Wow -- this was supposed to be a tiny heads up and it's grown into an essay of sorts!

So, basically, SWX Beta 1 is just around the corner and it's going to be great! Now I need to get to bed so I can get up and finalize this release tomorrow.

Comments