« September 2009 | Main | November 2009 »
October 30, 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:
Here's the code that creates a URLFilePromise for every file to be downloaded and puts them on the clipboard. But first, some code context:
onDragStartis the event handler that gets called when the user starts dragging items from the list of objects.bucketListis the ComboBox of bucket names.objectListis the DataGrid of objects.- The function
s3.getTemporaryObjectURL(...)generates a temporary public URL that points to the specified object. It's the URL that theURLFilePromisewill use to access the file.
private function onDragStart(e:DragEvent):void
{
if (bucketList.selectedIndex == 0 || objectList.selectedItems == null) return;
var c:Clipboard = new Clipboard();
var items:Array = objectList.selectedItems;
this.filePromises = new Array();
for each (var item:Object in items)
{
var fp:URLFilePromise = new URLFilePromise();
var req:URLRequest = new URLRequest(s3.getTemporaryObjectURL(bucketList.selectedItem.name, item.key, 60));
fp.request = req;
fp.relativePath = item.key;
this.filePromises.push(fp);
}
c.setData(ClipboardFormats.FILE_PROMISE_LIST_FORMAT, this.filePromises);
NativeDragManager.doDrag(objectList, c, null, null, null);
}
Below is the function that gets called when the drop is complete. It's responsible for opening the ProgressWindow component and passing it the array of URLFilePromise objects which the ProgressWindow component hooks into in order to receive progress events.
private function onDragComplete(e:DragEvent):void
{
var progressWindow:ProgressWindow = new ProgressWindow();
progressWindow.open(false);
progressWindow.setFilePromises(this.filePromises);
}
The code for S3E is open source and available on Google Code.
Posted by cantrell at 6:11 AM. Link | Comments (2) | References
October 29, 2009
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.
- Multi-touch: Touch events are similar to mouse events, but on multi-touch enabled devices, you can track multiple touch points simultaneously.
- Multi-touch support:
- Windows 7 and beyond.
- Requires multi-touch enabled hardware (obviously).
- Multi-touch support:
- Gestures: Applications can listen for multi-touch events, or gesture events (not both at the same time). Gestures are the synthesis of multi-touch events into a single event.
- Gesture support:
- Windows 7 and beyond.
- Macs running 10.6 and beyond with multi-touch trackpads.
- Type of gestures we support:
GESTURE_TWO_FINGER_TAP(tapping with two fingers)
GESTURE_PRESS_AND_TAP(holding one finger down, then tapping with another -- convention on some Windows devices for bringing up context menus)
GESTURE_PANGESTURE_ROTATEGESTURE_SWIPEGESTURE_ZOOM
- Gesture support:
- Open Files With Default Application: The new
File.openWithDefaultApplicationAPI lets you open a file instance with whatever application it happens to be associated with. This is a good cross-platform way to integrate with other applications since you don't have to know what applications are installed, or where. - OS Download Security Dialog: The new
File.downloadedproperty lets you indicate that a file was downloaded from the network and the OS should prompt the user with a confirmation dialog before opening it.- Supported platforms:
- Windows XP SP2 and later.
- Mac OS 10.5 (Leopard) and later.
- (No Linux support because Linux doesn't have this concept.)
- Supported platforms:
- Storage Volume Detection: The new storage volume APIs let you listen for the mounting and unmounting of storage volumes, list accessible volumes, and get information on storage volumes such as the file system type, whether it's removable, whether it's writable, the drive letter, and the drive label.
- Native Processes: Launch and communicate with native "out-of-band" processes. Bundle your own native executables, or call executables that you know are already on the machine. This feature requires that your application be installed with a native installer rather than though a .AIR file (we provide tools for building native installers).
- Types of installers:
- OS X: DMG
- Windows: EXE
- Linux: Debian and Red Hat Package Manager
- Types of installers:
- File Promises: File promises let users drag and drop files that either don't exist yet (because you want to generate them on-demand), or that exist on a remote server. We provide an implementation that will automatically download remote files for you and save them to the drop location, and we provide an interface for you to implement if you want to generate files on-demand.
- Server Sockets: The new
ServerSocketAPI let you listen on a socket so that you can implement inter-application communication, P2P applications, advanced network protocols like FTP, etc. - Datagram Sockets: In addition to TCP sockets, AIR 2.0 will now support UDP sockets.
- Encrypted Sockets: Sockets can now be encrypted using TLS/SSL.
- IPv6 Support.
- Access to Low-Level Network Information: The
NetworkInfoobject lets you enumerate network interfaces on the machine and get access to properties such as whether they are active, their IP address, and their display name. - Bind Sockets to Specific Network Interfaces: The new
Socket.bindfunction can be used to bind to a specific network interface (discovered through theNetworkInfoAPI) rather than always binding to the default. This can allow you to pick the best network connection for your particular application. - DNS Resolution: Use
DNSResolverto look up the following types of resource records:- ARecord (IPv4 address for a host)
- AAAARecord (IPv6 address for a host)
- MXRecord: mail exchange record for a host
- PTRRecord: host name for an IP address
- SRVRecord: service record for a service
- Configurable HTTP Idle Timeout.
URLRequest.idleTimeoutandURLRequestDefaults.idleTimeoutlet you specify the amount of time (in milliseconds) that a connection will remain open before it receives any data. This is useful for things like long polling. - Local Audio Encoding: Access audio data directly from the microphone. You used to have to send the data to a server and access it from there, but now you can do it entirely on the client.
- Global Error Handling: Global error handling lets you handle all uncaught errors (both synchronous errors and asynchronous error events) in one place in your code. (More information on Global Error Handling.)
- Accessibility: AIR 2.0 will have the same level of support for screen readers as Flash. (More information on accessibility in AIR 2.0.)
NativeWindowandBitmapSize Increases: The maximum size of aNativeWindowandBitmapinstance used to be 2880x2880. In AIR 2.0, it will be 4095x4095.- Improved Printing.
- Vector printing on Mac (already in FP 10).
- Complex transparency support.
- Nested Transactions. SQLite will now support nested transactions.
- Exiting Event on Shutdown. In AIR 2.0, you will be able to handle the
Event.EXITINGevent when the computer is shutting down so you will have an opportunity to save any unsaved work or data. - WebKit Upgrades:
- Nitro JavaScript Engine (SquirrelFish Extreme).
- CSS3 Module support (2D transformations, transitions, animations, etc.).
- Scrollbar styling.
- Break up text across columns.
- Latest Canvas enhancements.
- General Optimizations:
- Lower CPU utilization when idle.
- Lower memory consumption.
I think that's everything. A beta of AIR 2.0 will be on Adobe Labs late this year, and we hope to release in the first half of 2010. Questions?
Posted by cantrell at 10:44 AM. Link | Comments (43) | References
October 28, 2009
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.
Posted by cantrell at 10:46 AM. Link | Comments (7) | References
October 27, 2009
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.idleTimeoutURLRequestDefaults.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.
Posted by cantrell at 11:15 AM. Link | Comments (2) | References
October 26, 2009
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"]);
Posted by cantrell at 1:19 PM. Link | Comments (5) | References
October 23, 2009
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!
Posted by cantrell at 9:08 AM. Link | Comments (3) | References
October 9, 2009
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.
Posted by cantrell at 10:15 AM. Link | Comments (4) | References