Requirements
Prerequisite knowledge
To benefit most from this article, you should be familiar with the AIR runtime; Flex Builder, Aptana Studio, or Flash CS4 Professional; and ActionScript 3.0 or JavaScript.
Required products
Flex Builder (Download trial)
Adobe Animate CC CS4
Update framework
Download
Web server
Any web server will do. You need this for testing the update
User Level
Intermediate

Every time I create an AIR application that I know will be live someday, I always add support for updating it with the Adobe AIR update framework. Sooner rather than later, your application will need an update. Picture this: your application is a tremendous success and many people have installed it. A short time later you have a fix for a security issue, or you've just added the coolest feature ever. Suddenly you have a problem: how do you push this update to clients who already have installed your application?
 
If the application doesn't include support for the update process, then your problem is now a big one. The users will have to uninstall the current version, download the new one, and install it. This is hardly a friendly workflow.
 
The Adobe AIR update framework provides developers with APIs to create AIR applications that can be updated very easily. It comes in two flavors: one has a default user interface, and the other requires you to create your own UI and hook it up to the events that this framework provides.
 
The default user interface option uses Flex components; so if you are planning to create your AIR application using Flash, you can't use it. If you create the application with Flex or Ajax, you can use either one.
 
This article explains how to use the Adobe AIR update framework to easily and seamlessly push updates to AIR applications created using Flash, Flex, or Ajax.
 
In the first four sections I'm discussing the general workflow and how you can use it with AIR 1.5.x or 2. In the last two sections I talk about the changes in the update framework introduced by AIR 2.5.
 
Note: The update framework is not working for Extended Profile (Native installers) and for mobile applications.
 

 
How to use the Adobe AIR update framework

Using the update framework is easy. The simplest approach has three main steps (for an application created in Flex using the update framework with the default UI):
 
  1. Add the update library SWC file to your application.
  2. Create and add the updater descriptor file. This is a small XML file that keeps information needed by the updater (for example, what version is available, from where to take it, and what info to display). This file sits on your server, and when the application starts up it loads this file to see if any updates are available.
  3. Write about 10–15 lines of code in your AIR application—and you are done!
Figure 1 shows a typical workflow for an application that uses the update framework.
 
A typical workflow when the Adobe AIR update framework is used
Figure 1. A typical workflow when the Adobe AIR update framework is used
 
If the version number from the updater descriptor file is higher than the version number of the currently installed application (as set by the version tag from the application descriptor file), the update framework determines that a new version is available.
 
Furthermore, the version written in the updater descriptor file must be identical to the version set in the new AIR file (the packaged AIR application). If they are not, an error will be raised and the update will not be performed. For a list of the error codes that the framework can throw, refer to the language reference for ActionScript or HTML/JavaScript developers.
 
For version formats, you can use any of several conventions:
 
  • 0.9, 0.9.1, 1.0, 1.0.1
  • v1, v2, v2.1
  • a, b, c
To keep it simple and easy to follow, I use the first one.
 
 
Updating an application and security
One of the main benefits of the update framework is the ability to easily roll out updates to fix security issues. It would be a little ironic if the framework itself didn't provide security when it is used, and instead allowed an installed application to be downgraded, for example.
 
Fortunately, the update framework enhances the security of your application. For example, there is no way to "update" your application with an older version. This means that there is no way to accidentally roll out a version older than the ones that are installed by your clients. The same version number must be set in the AIR file (the AIR application packaged for release) and in the updater descriptor file. Furthermore, an AIR application can't be updated unless it was signed with the same certificate as the one that is being used to update it.
 
Keep in mind that the update framework needs a connection to the Internet or your local network. The new version and the updater descriptor files sit on a web server. Thus, when the application checks for updates it needs a connection to reach these files. If there is no connection, no update will be possible.
 
Because the Adobe AIR update framework is flexible, you decide how best to handle the update process. Your process can implement any of the following approaches:
 
  • When the application is started, have it check whether a new version is available.
  • Check for new updates at defined time intervals.
  • Let the user decide when to check for a new version, download the update, and install the file. Alternatively, you can enforce all these actions.
  • Notify the user what fixes or new features the update provides.

 
Using the framework in Flex apps built on AIR

Enough talk; time to look at some code. For the first example I will use Flex and the Adobe AIR update framework library with the user interface. To be honest I always use the version with the UI; I am too lazy to bother with creating my own UI.
 
Note: If you use CSS files to change the appearance of your AIR application and you use general styles (for example, for the Button or Scrollbar) that are not set as a class name but apply across your application, then these changes will also apply to the UI provided by the update framework. Keep this in mind, and always check the update framework UI when you use CSS.
 
If you don't want to create the project step by step, you can use the archive file provided with this article. To import the file, choose Import > Flex Builder > Flex Project and select the air_updater_flex.zip file.
 
 
Creating the AIR project in Flex Builder
Although you can create an AIR application using the command-line tools provided with the AIR SDK and your favorite text editor, I prefer to use Flex Builder:
 
  1. Open Flex Builder and choose New > Flex Project.
  2. For the project name, type air_updater_flex. For the Application type, select Desktop application (runs in Adobe AIR) (see Figure 2).
Creating the AIR project in Flex Builder
Figure 2. Creating the AIR project in Flex Builder
 
  1. Now it is time to copy the Adobe AIR update framework SWC file to the library folder of the project. For this, unzip the update framework ZIP file, and copy the applicationupdater_ui.swc file to the libs folder (see Figure 3).
Adding the update framework library to the project
Figure 3. Adding the update framework library to the project
 
  1. Create a folder inside of your web server root named updater. Add this folder to your project in order to be able to create and edit the content easily. To do this, choose New > Folder.
  2. In the wizard, select Advanced and then select Link to folder in the file system (see Figure 4). On my computer, the Apache web root is c:\htdocs, so for the folder path I typed c:\htdocs\updater. In this folder you will place the updater descriptor file and the application's AIR file.
Creating the link resource
Figure 4. Creating the link resource
 
 
Creating the Flex code
With all the bits in place, it is time to add the ActionScript to implement the update feature:
 
  1. Open the application file air_updater_flex.mxml and add a handler called checkUpdate for the event creationComplete of the WindowedApplication:
<?xml version="1.0" encoding="utf-8"?> <mx:WindowedApplication xmlns:mx="/2006/mxml" layout="absolute" creationComplete="checkUpdate()">
The function checkUpdate will be called every time the application is loaded.
 
  1. Add the remaining code for air_updater_flex.mxml shown below:
<mx:Script> <![CDATA[ import air.update.events.UpdateEvent; import mx.controls.Alert; import flash.events.ErrorEvent; import air.update.ApplicationUpdaterUI; /** * @var the object that that handles the update related actions */ private var appUpdater:ApplicationUpdaterUI = new ApplicationUpdaterUI(); /** * This function is triggered when the application finished to load; * Here we initialize <code>appUpdater</code> and set some properties */ private function checkUpdate():void { setApplicationVersion(); // we set the URL for the update.xml file appUpdater.updateURL = "http://localhost/updater/update.xml"; //we set the event handlers for INITIALIZED nad ERROR appUpdater.addEventListener(UpdateEvent.INITIALIZED, onUpdate); appUpdater.addEventListener(ErrorEvent.ERROR, onError); //we can hide the dialog asking for permission for checking for a new update; //if you want to see it just leave the default value (or set true). appUpdater.isCheckForUpdateVisible = false; //if isFileUpdateVisible is set to true, File Update, File No Update, //and File Error dialog boxes will be displayed appUpdater.isFileUpdateVisible = false; //if isInstallUpdateVisible is set to true, the dialog box for installing the update is visible appUpdater.isInstallUpdateVisible = false; //we initialize the updater appUpdater.initialize(); } /** * Handler function triggered by the ApplicationUpdater.initialize; * The updater was initialized and it is ready to take commands * (such as <code>checkNow()</code> * @param UpdateEvent */ private function onUpdate(event:UpdateEvent):void { //start the process of checking for a new update and to install appUpdater.checkNow(); } /** * Handler function for error events triggered by the ApplicationUpdater.initialize * @param ErrorEvent */ private function onError(event:ErrorEvent):void { Alert.show(event.toString()); } /** * A simple code just to read the current version of the application * and display it in a label. */ private function setApplicationVersion():void { var appXML:XML = NativeApplication.nativeApplication.applicationDescriptor; var ns:Namespace = appXML.namespace(); lblAppVersion.text = "App version:" + appXML.ns::version; } ]]> </mx:Script>
In this code, you add an mx:script tag and create a variable appUpdater that will keep a reference to the updater object (this object will be your interface to the framework). Then create the function checkUpdate(), which will be in charge of initializing and setting some values needed by the updater object. The updateURL property tells the updater where to find the updater descriptor file (you will create this file later). If you don't set the updateURL property correctly, the update will not work.
 
Next, you'll need to register two functions for the error event and initialized event. If the isCheckForUpdateVisible property is true, then the user is given the option to check for a new version or not. In this case, set it to false, which will bypass this dialog box when checking for a new version. The last function call, appUpdater.initialize(), does exactly what the name implies. When the updater is initialized it calls the listener you have registered for the initialize event, and inside this listener you start the process of checking for a new version.
 
The next two functions are the implementations for the event listeners for the error and initialize events. Once the onUpdate() listener gets called, it means the updater was initialized and it is ready to take commands. The onUpdate() function calls the method checkNow() on the updater, starting the update process.
 
The last function, setApplicationVersion(), just reads the current version of the app and displays it using a label.
 
Finally, add a label component to display the current version of the application:
 
<mx:VBox> <mx:Label id="lblAppVersion" width="300"/> </mx:VBox>
 
Creating the updater descriptor file
You have all the code in the application in place; now it is time to put in place the bits you need on the server. First create the file update.xml inside the updater folder from the project:
 
<?xml version="1.0" encoding="utf-8"?> <update xmlns="http://ns.adobe.com/air/framework/update/description/1.0"> <version>2.9</version> <url>http://localhost/updater/air_updater_flex.air</url> <description><![CDATA[ This version has fixes for the following known issues: *First issue *Second issue ]]></description> </update>
This file lets you define the URL where the new version of the application can be downloaded, set the version number, and specify the description text you want to display to the user.
 
 
Testing the code
All the code is in place but you are not finished yet. It is very important not to forget this: in order for the update to work you need to carefully set the same version number in two files—the updater descriptor file and the application descriptor (in my case, air_updater_flex-app.xml). In both these files you will find a version tag; what you put here needs to be exactly the same.
 
First, export the existing AIR application for release, and then install it. Now, you are ready to test the update:
 
  1. Open the update.xml file and application descriptor file (air_updater_flex-app.xml). In both files set the same version number (make sure it is higher than the current one), for example 2.9.
  2. Export the project for release and place it in the same folder as the update.xml file on your web server.
  3. Finally, start the application. You should see a dialog box (example in Figure 5).
The Adobe AIR update framework in action
Figure 5. The Adobe AIR update framework in action
 

 
Using the framework in Ajax apps built on AIR

To use the update framework with Ajax, you will need the applicationupdater_ui.swf file (the SWC file is used only for the AIR projects created in Flex). Again, I am too lazy to create a UI. And again, you can create the AIR application in your favorite text editor and use the command-line tools to test and package. However, I prefer to use Aptana.
 
 
Setting up the AIR project in Aptana Studio
Note: If you don't want to go through step-by-step instructions to create the project, you can use the archive provided with this article, air_update_ajax.zip. To import it in Aptana, choose Import > General > Archive File.
 
To set up an AIR project in Aptana Studio:
 
  1. Open Aptana and choose New > Project.
  2. In the open window select Adobe AIR Project from Aptana Projects and click Next.
  3. Type air_update_ajax as the project name, and then click Next (see Figure 6).
First page of the Adobe AIR Project Wizard; setting the project name
Figure 6. First page of the Adobe AIR Project Wizard; setting the project name
 
  1. On the next page, remove the underscores from the ID value (Aptana Studio will raise an error if the ID string contains underscore characters) as shown in Figure 7.
Second page of the Adobe AIR Project Wizard; removing the underscores from the ID value
Figure 7. Second page of the Adobe AIR Project Wizard; removing the underscores from the ID value
 
  1. Click Next, and then Finish.
After creating the project, add the external folder updater, the folder that holds the new version of the application and the update descriptor file (see Figure 4 and the associated explanation on how to do this). I will reuse the same folder (c:\htdocs\updater) that I used for the Flex example.
 
At this point you should see something like the image shown in Figure 8 (my air_update_ajax.html file may differ from yours because I deleted the comments and some unnecessary JavaScript code).
 
The AIR project in Aptana
Figure 8. The AIR project in Aptana
 
Adding the code for update
Now you need to copy the Adobe AIR update framework library (applicationupdater_ui.swf ) to your project. To add this library to the application:
 
  1. Open the air_update_ajax.html file and add this tag to the head section:
<script src="applicationupdater_ui.swf" type="application/x-shockwave-flash"/>
The page should look like this:
 
<html> <head> <title>AIR AJAX Update Example</title> <link href="sample.css" rel="stylesheet" type="text/css"/> <script type="text/javascript" src="AIRAliases.js"></script> <script src="applicationupdater_ui.swf" type="application/x-shockwave-flash"/> </head> <body> </body> </html>
  1. Add the following code, which instantiates an updateUI object, in the head section of the air_update_ajax.html file:
<script> // instantiate an updater object var appUpdater = new runtime.air.update.ApplicationUpdaterUI(); function checkUpdate() { // we set the URL for the update.xml file appUpdater.updateURL = "http://localhost/updater/update.xml"; //we set the event handlers for INITIALIZED nad ERROR appUpdater.addEventListener(runtime.air.update.events.UpdateEvent.INITIALIZED, onUpdate); appUpdater.addEventListener(runtime.flash.events.ErrorEvent.ERROR, onError); //we can hide the dialog asking for permission for checking for a new update; //if you want to see it just leave the default value (or set true). appUpdater.isCheckForUpdateVisible = false; //if isFileUpdateVisible is set to true, File Update, File No Update, //and File Error dialog boxes will be displayed appUpdater.isFileUpdateVisible = false; //if isInstallUpdateVisible is set to true, the dialog box for installing the update is visible appUpdater.isInstallUpdateVisible = false; //we initialize the updater appUpdater.initialize(); } function onUpdate(event) { //starts the update process appUpdater.checkNow(); } function onError(event) { alert(event); } </script>
In the code above, the function checkUpdate() is called each time the application is started. Inside this function, you configure the updater object: set up the URL for the update descriptor file, set up the UI to be displayed, and register two listeners for initialized and error events. The last line of this function initializes the updater object.
 
After the updater object is initialized, the onUpdate() function gets called and the object is ready to take commands. At this point, the code calls the checkNow() method on the updater object to start the update process (if a new version is found on the server).
 
Lastly, you need to hook up the call to the checkUpdate() function to the onload event of the application:
 
<body onload="checkUpdate()">
 
Creating the update.xml file
Now that you've finished coding the application, you need to create the code that stays on the server. First create the update.xml file inside the updater folder from the project. Add this code to the file:
 
<?xml version="1.0" encoding="utf-8"?> <update xmlns="http://ns.adobe.com/air/framework/update/description/1.0"> <version>2.9</version> <url>http://localhost/updater/air_updater_ajax.air</url> <description><![CDATA[ This version has fixes for the following known issues: *First issue *Second issue ]]></description> </update>
It is important to correctly set the URL to the packaged application using the <url> tag. On my machine the URL to the updater folder is http://localhost/updater/, and because I chose to place the application in the same folder, the URL is http://localhost/updater/air_update_ajax.air.
 
There are more options you can set in this file; see the AIR_Update_Framework.pdf file that comes with update framework for more details.
 
 
Testing the code
With the code in place, you are ready to test it. First, you need to export the application and install it on your machine. Choose Export > Adobe AIR > Adobe AIR Package (deselect from the list updater folder).
 
Next, install the application on your machine.
 
To test the first update, you need to create a new (higher) version of the application:
 
  1. Open the update.xml file and application.xml files, and set the <version> tags to the same value, for example 3.0.
  2. Export the application (choose Export > Adobe AIR > Adobe AIR Package), and place the AIR file inside of the updater folder on your web server.
  3. Start the installed application. You should see a screen like the one shown in Figure 9.
An offer to update the AIR Ajax application
Figure 9. An offer to update the AIR Ajax application

 
Using the framework in Flash apps built on AIR

If you develop AIR applications using Flash (that is, not using the Flex framework), you can still use the Adobe AIR update framework. With Flash, however, you can't use the library with the default UI, since this library uses the Flex framework. As a result, there is a little more work needed to implement the update logic and the UI.
 
If you don't want to create the project step by step, you can use the archive (air_update_flash.zip) provided with this article. You'll still need to extract the applicationupdater.swc file from the update framework archive, and add it to the project paths (see the next section).
 
 
Creating the project
Choose File > New > Flash File (Adobe AIR) and then click OK. Next, choose File > Save and type air_update_flash.fla as the name.
 
To add the applicationupdater.swc file to the project:
 
  1. Choose File > Publish Settings.
  2. Select the Flash tab, and click the Settings button for the "Script" option.
  3. Select the Library path tab (see Figure 10), and click the plus (+) button, then click the "Browse to SWC file" button (the red one) and select the applicationupdater.swc file.
  4. Click OK.
Adding the applicationupdater.swc file to the library path
Figure 10. Adding the applicationupdater.swc file to the library path
 
To test that the library was added to the project, switch to Source mode and enter the following ActionScript code:
 
import air.update.ApplicationUpdater; var appUpdater:ApplicationUpdater = new ApplicationUpdater();
Run the application; if the library has been added to the project you won't see any errors.
 
 
Adding code for the update
Note: I am not a Flash developer, and it is quite possible that someone more experienced with Flash than I am could write code that is more efficient or more elegant.
 
  1. Switch to Design mode and add four text boxes to air_update_flash.fla (see Figure 11). Make two of them static text and type Application name:, and Version:. Set the other two as dynamic text, and give them the following IDs: lblName and lblVersion.
Adding the UI components to the main application window
Figure 11. Adding the UI components to the main application window
 
You will use these controls to display the application name the current version.
 
As I noted earlier, because you are using the update framework without the default UI, you have to implement the UI yourself. To do this, you can create a custom component (a movie clip) named myWindow. You will use this component to draw the content of the pop-up window that will display the various states while updating the application. Because the logic for updating the application resides in a FLA file, you need a way to control this component's appearance from the main application.
 
  1. Create a new ActionScript file (myWindow.as) in the same folder as the air_update_flash.fla file. In this file, insert the following code:
package { public class myWindow extends MovieClip { } }
  1. You are ready now to create the movie clip that you will use to draw the content of the pop-up window. Select the Library panel and click New Symbol. For the Name type myWindow, for Type select Movie Clip, and then click Advanced.
  2. Select Export for ActionScript and Export in frame 1 in the Linkage section (see Figure 12). For the Class, type myWindow (this is the class you defined in the myWindow.as file).
Create the movie clip component
Figure 12. Create the movie clip component
 
  1. Click OK.
  2. It is time to add the UI elements to this component. From the Library panel choose the myWindow component, and click Edit. Add a black background, then add a text box (make it dynamic), and select a larger font size. Below this text box, add a text area and a progress bar. Finally, add two buttons aligned bottom-right (see Figure 13). Save the file.
Adding the UI components to the myWindow movie clip
Figure 13. Adding the UI components to the myWindow movie clip
 
Basically, you set up all the components needed to draw the windows you will show. When you use the component, you can choose which components to show, which components to hide, what the text and labels will be, and so on.
 
  1. Add the IDs for these components: title_1 for the first text box, description_1 for the text area, bar_1 for the progress bar, button_1 and button_2 for the two buttons.
  2. You need to make these components available to the main application. For this, open the myWindow.as file and add this code:
package { import flash.display.MovieClip; import fl.controls.ProgressBar; import fl.controls.Button; import fl.controls.TextArea; //this class sets the type for the myWindow component //we use it as a proxy to the UI controls from the myWindow component //(buttons, labels, text area, or progress bar) public class myWindow extends MovieClip { public function set title(text:String):void { title_1.text = text; } public function set description(text:String):void { description_1.text = text; } public function set enableDescription(enable:Boolean):void { description_1.visible = enable; } public function enableBar(enable:Boolean):void { bar_1.visible = enable; } public function get bar():ProgressBar { return bar_1; } public function get buttonLeft():Button { return button_1; } public function get buttonRight():Button { return button_2; } } }
Now you can access each component from the main application.
 
  1. It is time to move back to air_update_flash.fla and add the business logic. Select the file, and then open the Actions Frame and select Scene 1, Layer 1: Frame 1. You should see the code you added before:
import air.update.ApplicationUpdater; var appUpdater:ApplicationUpdater = new ApplicationUpdater();
Here is the complete code followed by an explanation:
 
import air.update.ApplicationUpdater; import air.update.events.StatusFileUpdateEvent; import air.update.events.StatusUpdateErrorEvent; import air.update.events.StatusFileUpdateErrorEvent; import air.update.events.DownloadErrorEvent; import air.update.events.StatusUpdateEvent; import air.update.events.UpdateEvent; import flash.events.ErrorEvent; import flash.events.MouseEvent; import flash.desktop.NativeApplication; import flash.display.NativeWindow; import flash.display.NativeWindowInitOptions; import flash.display.NativeWindowSystemChrome; import flash.display.NativeWindowType; import flash.display.StageScaleMode; import flash.display.StageAlign; import fl.controls.Button; import Namespace; import XML; var appUpdater:ApplicationUpdater = new ApplicationUpdater(); var window:NativeWindow; var windowContent:myWindow = new myWindow(); var existentListeners:Dictionary = new Dictionary(); //initialize the updater; gets called when the application is loaded function initializeUpdater():void { setApplicationNameAndVersion(); appUpdater.updateURL = "http://localhost/updater/update_flash.xml"; //we set the event handlers for INITIALIZED nad ERROR appUpdater.addEventListener(UpdateEvent.INITIALIZED, onUpdate); appUpdater.addEventListener(ErrorEvent.ERROR, onError); appUpdater.addEventListener(StatusUpdateEvent.UPDATE_STATUS, onStatusUpdate); appUpdater.addEventListener(StatusUpdateErrorEvent.UPDATE_ERROR, onStatusUpdateError); appUpdater.addEventListener(ProgressEvent.PROGRESS, onDownloadProgress); appUpdater.addEventListener(UpdateEvent.DOWNLOAD_COMPLETE, onDownloadComplete); appUpdater.addEventListener(DownloadErrorEvent.DOWNLOAD_ERROR, onDownloadError); //initialize the updater appUpdater.initialize(); } //listener for INITIALIZED event of the applicationUpdater; function onUpdate(event:UpdateEvent):void { //start the process of checking for a new update and to install appUpdater.checkNow(); } //Handler function for error events triggered by the ApplicationUpdater.initialize function onError(event:ErrorEvent):void { trace(event); createWindow(); displayWindowError(event.errorID, event.text); } //handler function for StatusUpdateEvent.UPDATE_STATUS //this is called after the update descriptor was downloaded and interpreted successfuly function onStatusUpdate(event:StatusUpdateEvent):void { trace(event); //prevent the default (start downloading the new version) event.preventDefault(); createWindow(); windowContent.bar.visible = false; //hide the progress bar //create the window for displaying Update available if (event.available) { windowContent.title = "Update Available"; windowContent.enableDescription = true; windowContent.description = event.version + " " + event.details[0][1]; windowContent.buttonLeft.label = "Update"; windowContent.buttonRight.label = "Cancel"; addEventToButton(windowContent.buttonLeft, MouseEvent.CLICK, startDownload); addEventToButton(windowContent.buttonRight, MouseEvent.CLICK, closeWindow); //we don't have an update, so display this information } else { windowContent.title = "No Update Available"; windowContent.enableDescription = false; windowContent.buttonLeft.visible = false; windowContent.buttonRight.label = "Close"; addEventToButton(windowContent.buttonRight, MouseEvent.CLICK, closeWindow); } } //error listener for an error when the updater could not download or //interpret the update descriptor file. function onStatusUpdateError(event:StatusUpdateErrorEvent):void { createWindow(); displayWindowError(event.subErrorID, event.text); } //error listener for DownloadErrorEvent. Dispatched if there is an error while connecting or //downloading the update file. It is also dispatched for invalid HTTP statuses //(such as "404 - File not found"). function onDownloadError(event:DownloadErrorEvent):void { createWindow(); displayWindowError(event.subErrorID, event.text); } //start the download of the new version function startDownload(event:MouseEvent):void { appUpdater.downloadUpdate(); createWindow(); windowContent.bar.visible = true; windowContent.bar.setProgress(0, 100); } //listener for the ProgressEvent when a download of the new version is in progress function onDownloadProgress(event:ProgressEvent):void { windowContent.bar.setProgress(event.bytesLoaded, event.bytesTotal); } //listener for the complete event for downloading the application //just close the window; the downloaded version will be automatically installed, //and then the application gets restarted function onDownloadComplete(event:UpdateEvent):void { closeWindow(null); } //sets the state of the window in error display mode function displayWindowError(errorId:int, errorText:String):void { windowContent.title = "Error"; windowContent.enableDescription = true; windowContent.description = "Error ID: " + errorId + ". " + errorText; windowContent.buttonLeft.visible = false; windowContent.buttonRight.label = "Close"; windowContent.bar.visible = false; addEventToButton(windowContent.buttonRight, MouseEvent.CLICK, closeWindow); } //create a window using NativeWindow, and as a content myWindow class function createWindow():void { if (window == null) { var options:NativeWindowInitOptions = new NativeWindowInitOptions(); options.systemChrome = NativeWindowSystemChrome.STANDARD; options.type = NativeWindowType.NORMAL; window = new NativeWindow(options); window.x = 300; window.y = 200; window.stage.stageHeight = 230; window.stage.stageWidth = 450; window.stage.scaleMode = StageScaleMode.NO_SCALE; window.stage.align = StageAlign.TOP_LEFT; window.stage.addChild(windowContent); windowContent.bar.visible = false; } window.alwaysInFront = true; window.visible = true; } //close the window function closeWindow(event:Event):void { window.close(); } //hide the window function hideWindow():void { window.visible = false; } //sets the application name and version in the main window function setApplicationNameAndVersion():void { var appXML:XML = NativeApplication.nativeApplication.applicationDescriptor; var ns:Namespace = appXML.namespace(); lblVersion.text = appXML.ns::version; lblName.text = appXML.ns::name; } //add to the given button, the listener for given type (actually we use only the type MouseEvent.CLICK). //we use a dictionary to store for each button the listener registered. //when this function gets called, first we remove any registered listener. Next we register the listener //on the button, and next we save to dictionary. function addEventToButton(button:Button, type:String, listener:Function):void { //remove existent listneres if (existentListeners[button] != null) { var arr:Array = existentListeners[button] as Array; button.removeEventListener(type, arr[0]); } existentListeners[button] = []; button.addEventListener(type, listener); existentListeners[button][0] = listener; button.visible = true; } initializeUpdater(); //initialize the updater
This code does the following:
 
  • It uses a NativeWindow instance and a myWindow instance (the component you created earlier) to draw the pop-up window (see the function createWidow() in the code).
  • The function initializeUpdater() is called once the application is loaded. This function initializes the update framework object (appUpdater), sets the URL for the update descriptor file (on my machine the path is http://localhost/updater/update_flash.xml), and registers listeners for different events on the update object. While I chose a minimal implementation (I intend to show a window if an update is available or not, to display the window while the update is downloaded, and to display an error window if something goes wrong), you can implement more windows (see the documentation for more details).
  • The code implements each listener registered on the updater object.
  • The function setApplicationNameAndVersion() is called from initializeUpdater() and sets the application name and version in the UI in the main application window.
  • There is also a function for creating the pop-up window (createWindow), and functions to hide and close the window.
 
Testing the code
You have almost all the bits in place. You have to write the update descriptor file, and set the URL of the applicationUpdater (this is set in the initializeUpdater() function) to point to this file.
 
  1. Inside of your web server root create a folder called updater. In this folder create the file update_flash.xml, and add the following XML to it:
     
     
<?xml version="1.0" encoding="utf-8"?> <update xmlns="http://ns.adobe.com/air/framework/update/description/1.0"> <version>1.2</version> <url>http://localhost/updater/air_update_flash.air</url> <description><![CDATA[ This version has fixes for the following known issues: *First issue *Second issue ]]></description> </update>
  1. Choose File > Publish to create an AIR file for this project. You should see an air_update_flash.air file in the same folder as the air_update_flash.fla file. Install the application.
  2. In Flash CS4 choose File > Publish Settings, select the Flash tab, and click Settings next to the Player option. Increase the version number (see Figure 14), and then click Publish AIR File.
Increase the version number and publish the project.
Figure 14. Increase the version number and publish the project.
 
  1. Copy the AIR file to your web server, inside the updater folder. Open the update_flash.xml file from the same folder, and set the version to the same number you used for the project you just published. Also, make sure that the URL to the AIR file is correct.
  2. Now you can open the installed application and you should see something like the window shown Figure 15.
The custom updater UI
Figure 15. The custom updater UI
 
  1. Click Update to start the update process. The new version is downloaded and installed, and then the application is restarted (see Figure 16).
The update was installed successfully.
Figure 16. The update was installed successfully.
 

 
Using the update framework in applications created with AIR 2.5 or later

AIR 2.5 introduces a number of changes for the Update framework. Although the general principles and worflow remain the same, you'll notice the following differences when you use the update framework with AIR 2.5 or later:
 
  • Update descriptor file changes:
    • The updater descriptor file namespace has changed from 1 to 2.5.
    • The <version> tag has changed to <versionNumber>
    • There is a new tag called <versionLabel> that you should use for displaying the version to the user. This tag si not mandatory. You can set any string you want (see figure 17 for an example of this tag usage)
    • In the past you could have used almost anything for defining a version sequence. Now you should use this format for <versionNumber>: <0-999>.<0-999>.<0-999> (or variants); any of the following are correct: 1.1.2, 1.4, 0.9.1, or 1
  • In your AIR application you have to use NativeApplication.nativeApplication.applicationDescriptor.versionNumber
    instead of
    NativeApplication.nativeApplication.applicationDescriptor.version
    when you want to retrieve the current application version number (or you can use the currentVersion property of the ApplicationUpdater/ApplicationUpdaterUI – this property is set after the initialize() method call)
  • In the application descriptor file:
    • The updater descriptor file namespace has changed from 1 to 2.5.
    • The <version> tag has changed to <versionNumber>; you should use this format <0-999>.<0-999>.<0-999>
    • There is a new tag called <versionLabel> that you should use for displaying the application version to the user
Using the <versionLabel> new tag
Figure 17. Using the new tag.
 
Here is an an example of the new update descriptor file:
 
<?xml version="1.0" encoding="utf-8"?> <update xmlns="http://ns.adobe.com/air/framework/update/description/2.5"> <versionNumber>0.9.2</versionNumber> <versionLabel>Beta 2</versionLabel> <url>http://localhost/updater/AIRUpdater.air</url> <description><![CDATA[ This version has fixes for the following knowns issues: *First issue *Second issue ]]></description> </update>
If you forget to update the update descriptor file namespace to 2.5, then you will get this error: Error# 16831 (see Figure 18).
 
Error# 16831 when the update descriptor file namespace is set to 1.0.
Figure 18. Error# 16831 when the update descriptor file namespace is set to 1.0.
 
If you forget to use the <versionNumber> tag instead of <version> in the update descriptor file and the namespace is set to 2.5, you will get this error: Error# 16816 (see Figure 19).
 
Error# 16816 you use<version> instead of <versionNumber>.
Figure 19. Error# 16816 you use <version> instead of <versionNumber>.
 

 
Updating applications created with AIR 1.x or 2 to AIR 2.5 or later

If you have an application created with a version of AIR that is older than 2.5 and you want to update the application to AIR 2.5 or later, you have to implement a two-step update process:
 
  1. Update the application to the AIR 2.5 (or later) version of the Application Update framework.
  2. Update the application to the 2.5 namespace.
  3. Upload the updated files.
Here is the breakdown of this process:
 
 
Step 1: Update the application to AIR 2.5 (or later)
Suppose the current version of your application is 2.0 and that it is built using Adobe AIR 1.5; the first thing you want to do is to create an interim version of the application that uses the update framework from AIR 2.5.
 
  1. This application will be version 2.1–so open the application descriptor file and change the version from 2.0 to 2.1 and then save the file.
  2. Change the version number in the update descriptor file to 2.1 (use the file name update.xml for this example). Here is an example:
<?xml version="1.0" encoding="utf-8"?> <update xmlns="http://ns.adobe.com/air/framework/update/description/1.0"> <version>2.1</version> <url>http://localhost/updater/air_update_flex.air</url> <description><![CDATA[ ]]></description> </update>
  1. Open the project properties and go to the Flex Build Path. Open the Flex node and remove these two SWC files: applicationupdater_ui.swc and applicationupdater.swc. Then click the Add SWC button and select the applicationupdater_ui.swc and applicationupdater.swc from the AIR SDK 2.5. Click OK to apply these changes (see Figure 20).
Updateing the update framework SWC files to 2.5
Figure 20. Updateing the update framework SWC files to 2.5.
 
  1. In your AIR application you need to change the URL for the update descriptor file to a new file update descriptor file. For this example I will use a new file called update_to_2_5.xml:
appUpdater.updateURL = "http://localhost/updater/update_to_2_5.xml"; //previous update descriptor file //appUpdater.updateURL = "http://localhost/updater/update.xml";
  1. Create the new update descriptor file (update_to_2_5.xml). This file uses the AIR 1.5 format. This file also points to final version of your application, version 2.5, that uses AIR 2.5 SDK and features. Here is an example:
<?xml version="1.0" encoding="utf-8"?> <update xmlns="http://ns.adobe.com/air/framework/update/description/1.0"> <version>2.5</version> <url>http://localhost/updater/air_update_flex-2.5.air</url> <description><![CDATA[ ]]></description> </update>
  1. Export this application (in our example this app will be exported as air_update_flex.air).
 
Step 2: Update the application to the 2.5 namespace
Next, you need to create the final version of your application, the one that is uses the AIR 2.5 SDK and it is compiled with this version of the SDK. From the point of view of the update process there are five steps:
 
  1. Edit the application descriptor file to use 2.5 namespace.
  2. Edit the application descriptor file and change the <version> to <versionLabel>. Also, for this example, change the number from 2.1 to 2.5.
  3. Edit the project properties and change the AIR SDK to 2.5 version.
  4. Create a third update descriptor file, this one using the AIR 2.5 format and this is the one that will be used from now on. For this example, call it update_2_5_final.xml:
<?xml version="1.0" encoding="utf-8"?> <update xmlns="http://ns.adobe.com/air/framework/update/description/2.5"> <versionNumber>2.5</versionNumber> <versionLabel>Version for 2.5</versionLabel> <url>http://localhost/updater/air_update_flex-2.5.air</url> <description><![CDATA[ ]]></description> </update>
  1. Change the URL for the updateURL property to point to this new update descriptor file.
appUpdater.updateURL = "http://localhost/updater/update_2_5_final.xml";
Once you've done this, you should be able to compile the project. For this example, the version will be saved as air_update_flex-2_5.air file.
 
 
Step 3: Upload your files
After you have created all the files you need, you will proced to uploading them to your server. First upload the application files (in this example air_update_flex.air and air_update_flex-2_5.air) and then the update descriptor files (update.xml, update_to_2_5.xml, and update_2_5_final.xml).
 
By respecting this order, you ensure that no user will experience a break during the update process due to missing files or wrong versions.
 

 
Where to go from here

The Adobe AIR update framework enables you to add a very important and useful feature to your applications: the ability to push updates to your users very easily. The update framework supports Flex, Ajax, and Flash, so you're covered no matter what technology you prefer for developing AIR applications.
 
For more AIR resources, visit the AIR Developer Center. Also, take time to read the documentation that comes with the framework. You'll discover how flexible it is, and how you can customize it to meet your needs.