Archive for October, 2009

A Screencast Explaining and Demoing File Promises

File promises are kind of a difficult concept to describe, so I decided to explain them using a video. Hopefully this clarifies what file promises are, and why it’s such a cool new feature of AIR 2.0:

Continue reading…

Exhaustive List of Everything That’s New in AIR 2.0

This morning, I was going to start making videos demoing some of the new features in AIR 2.0 when I realized that I should probably start with a list of everything that’s new. Below is an exhaustive list of everything that we’re planning on including in AIR 2.0. I use the word planning because even at this relatively late stage, things can change. Consider yourself warned.

Feel free to post questions in the comments.

Continue reading…

Global Error Handling in AIR 2.0 and Flash 10.1

One of the most popular feature announcements during my MAX presentation was global error handling (GEH). GEH lets you handle all uncaught errors (both synchronous errors and asynchronous error events) in one place in your code. Here’s an example of how it will work:

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" applicationComplete="onApplicationComplete();">

<mx:Script>
<![CDATA[
private function onApplicationComplete():void
{
loaderInfo.uncaughtErrorEvents.addEventListener(UncaughtErrorEvent.UNCAUGHT_ERROR, onUncaughtError);
}

private function onUncaughtError(e:UncaughtErrorEvent):void
{
// Do something with your error.
if (e.error is Error)
{
var error:Error = e.error as Error;
trace(error.errorID, error.name, error.message);
}
else
{
var errorEvent:ErrorEvent = e.error as ErrorEvent;
trace(errorEvent.errorID);
}
}

private function onCauseError(e:MouseEvent):void
{
var foo:String = null;
try
{
trace(foo.length);
}
catch (e:TypeError)
{
trace("This error is caught.");
}

// Since this error isn't caught, it will cause the global error handler to fire.
trace(foo.length);
}
]]>
</mx:Script>

<mx:Button label="Cause TypeError" click="onCauseError(event);"/>

</mx:WindowedApplication>

Registering for uncaught errors is hugely convenient, but it doesn’t entirely excuse developers from handling errors where they’re most likely to happen. For instance, you should still always register for things like IOError events and other errors that are likely to happen at some point, and that you can usually recover from. But starting with AIR 2.0 (and FP 10.1), you will also be able to register globally for errors that you weren’t able to anticipate, and handle them at least somewhat gracefully.

The big question is what you do once you’ve caught an unhandled error. That will probably depend on the application. Since it’s likely that a function exited without executing all the way through, there’s no telling what state your app will be in. The safest thing to do is probably to log the error, show a very contrite dialog box, and then exit the app (after all, if the error had been predictable and easy to recover from, you should have caught it explicitly). You might try sending the error message to your server, including instructions for emailing the log file to a support email address, or if it’s an internal application, provide a telephone extension to call for someone to come take a look. It’s entirely up to you. We provide the API, you provide the solution.

New AIR 2.0 API: URLRequest.idleTimeout

We recently added a new AIR 2.0 API which didn’t make it into my MAX presentation:

  • URLRequest.idleTimeout
  • URLRequestDefaults.idleTimeout

These setters specify the amount of time (in milliseconds) that a connection will remain open before receiving any data. Certainly not as sexy as some of our other new features (native processes, file promises, multi-touch, accessibility, volume detection, socket servers, etc.), but if you’re trying to use long polling, you’ll probably find this API useful.

Referencing ActionScript Reserved Words in E4X

If you have a chunk of XML with reserved ActionScript words in it, you won’t be able to use E4X syntax like you’re used to. For instance, say you need to parse the following XML:

var codeXML:XML =
<code>
<class name="Order">
<function name="getId">
<access>public</access>
<return>Number</return>
</function>
</class>
</code>;

Since this XML is full of reserved words, you won’t be able to access nodes like this:

trace(codeXML.class.function.return);

Instead, use bracket syntax like this:

trace(codeXML["class"].@name);
trace(codeXML["class"]["function"].access);
trace(codeXML["class"]["function"]["return"]);

Generating Dynamic XML With E4X in ActionScript

E4X makes working with XML in ActionScript extremely simple. Creating some XML is as easy as this:

var inventory:XML =
<inventory>
<product id="111" price="2999.99">Laptop</product>
</inventory>;

But what if you want to generate the XML dynamically and use variables as attribute values or text nodes? Just use curly braces like this:

var products:Array = new Array();

products.push({name:"Laptop", id:111, price:2999.99});
products.push({name:"Mouse", id:222, price:49.99});
products.push({name:"Phone", id:333, price:199.99});

var inventory:XML = <inventory/>;

for each (var o:Object in products)
{
inventory.appendChild(<product id={o.id} price={o.price}>{o.name}</product>);
}

The resulting XML is exactly what you’d expect:

<inventory>
<product id="111" price="2999.99">Laptop</product>
<product id="222" price="49.99">Mouse</product>
<product id="333" price="199.99">Phone</product>
</inventory>

Simple and elegant!

My MAX Presentation is Online: What’s Coming in AIR 2.0

A video of my MAX 2009 presentation entitled "What’s Coming in AIR 2.0" is now online. You can also download the slides (PDF) separately.

Feel free to leave questions in the comments.