The Space For App Developers

Beyond Plain Old HTML Objects

Building NativeApplicationUpdater custom UI

with 16 comments

After I published the NativeApplicationUpdater library I received a lot of questions how to display a UI showing download and install progress. Unfortunately NAU doesn’t come with a built-in UI yet ;) So I decided to put together this short blog post to explain how you can build it yourself. Below you can see how the demo app with the custom UI looks (project source code is available here in SVN):




Below is snippet of code that you can examine to better understand how to build your own updater UI:

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009" 
					   xmlns:s="library://ns.adobe.com/flex/spark" 
					   xmlns:mx="library://ns.adobe.com/flex/mx"
					   xmlns:updater="http://updater.riaspace.com/">
 
	<fx:Script>
		<![CDATA[
			import air.update.events.DownloadErrorEvent;
			import air.update.events.StatusUpdateEvent;
			import air.update.events.UpdateEvent;
 
			import mx.controls.Alert;
 
			[Bindable]
			protected var downlaoding:Boolean = false;
 
			protected function isNewerFunction(currentVersion:String, updateVersion:String):Boolean
			{
				// Example of custom isNewerFunction function, it can be omitted if one doesn't want
				// to implement it's own version comparison logic. Be default it does simple string
				// comparison.
				return true;
			}
 
			protected function updater_errorHandler(event:ErrorEvent):void
			{
				Alert.show(event.text);
			}
 
			protected function btnCheckNow_clickHandler(event:MouseEvent):void
			{
				// First initialize NativeApplicationUpdater
				updater.initialize();
			}
 
			protected function updater_initializedHandler(event:UpdateEvent):void
			{
				// When NativeApplicationUpdater is initialized you can call checkNow function
				updater.checkNow();
			}
 
			protected function updater_updateStatusHandler(event:StatusUpdateEvent):void
			{
				if (event.available)
				{
					// In case update is available prevent default behavior of checkNow() function 
					// and switch to the view that gives the user ability to decide if he wants to
					// install new version of the application.
					event.preventDefault();
					currentState = "updaterView";
				}
				else
				{
					Alert.show("Your application is up to date!");
				}
			}
 
			protected function btnYes_clickHandler(event:MouseEvent):void
			{
 
				// In case user wants to download and install update display download progress bar
				// and invoke downloadUpdate() function.
				downlaoding = true;
				updater.addEventListener(DownloadErrorEvent.DOWNLOAD_ERROR, updater_downloadErrorHandler);
				updater.addEventListener(UpdateEvent.DOWNLOAD_COMPLETE, updater_downloadCompleteHandler);
				updater.downloadUpdate();
			}
 
			protected function btnNo_clickHandler(event:MouseEvent):void
			{
				currentState = "mainView";
			}
 
			private function updater_downloadCompleteHandler(event:UpdateEvent):void
			{
				// When update is downloaded install it.
				updater.installUpdate();
			}
 
			private function updater_downloadErrorHandler(event:DownloadErrorEvent):void
			{
				Alert.show("Error downloading update file, try again later.");
			}
 
		]]>
	</fx:Script>
 
	<s:states>
		<s:State name="mainView"/>
		<s:State name="updaterView"/>
	</s:states>
 
	<fx:Declarations>
		<updater:NativeApplicationUpdater id="updater" 
					updateURL="http://riaspace.com/native-application-updater/update-1.1.xml" 
					isNewerVersionFunction="{isNewerFunction}"
 
					initialized="updater_initializedHandler(event)"
					updateStatus="updater_updateStatusHandler(event)"
 
					error="updater_errorHandler(event)"
					downloadError="updater_errorHandler(event)"
					updateError="updater_errorHandler(event)"
					/>
	</fx:Declarations>
 
	<s:Button id="btnCheckNow" label="Check for updates" includeIn="mainView" 
			  horizontalCenter="0" verticalCenter="0" 
			  click="btnCheckNow_clickHandler(event)"/>
 
	<s:HGroup verticalCenter="0" includeIn="updaterView" horizontalCenter="0" verticalAlign="top">
		<s:BitmapImage source="@Embed(source='/assets/icon128.png')" />
		<s:VGroup width="100%" horizontalAlign="center">
			<s:Label text="New version ({updater.updateVersion}) is available." />
			<s:Label text="Do you want to download it and install?" />
			<mx:ProgressBar id="prgBar" source="{updater}" label="Downloading %3%" visible="{downlaoding}" />
			<s:HGroup>
				<s:Button id="btnYes" label="Yes" click="btnYes_clickHandler(event)" />
				<s:Button id="btnNo" label="No" click="btnNo_clickHandler(event)" />
			</s:HGroup>
		</s:VGroup>
	</s:HGroup>
 
</s:WindowedApplication>

Written by Piotr Walczyszyn

October 15th, 2010 at 3:04 pm

Posted in Examples,Releases

Tagged with ,

16 Responses to 'Building NativeApplicationUpdater custom UI'

Subscribe to comments with RSS or TrackBack to 'Building NativeApplicationUpdater custom UI'.

  1. [...] can see how the demo app with custom UI looks (project source code is available here in SVN): via Building NativeApplicationUpdater custom UI at Space of Flex/AIR technologies. [...]

  2. Does it work with air 2.5 or has the issue been solved by Adobe now?

    Hugo

    30 Dec 10 at 9:46 am

  3. [...] Open Source NativeApplicationUpdater (AIR) //Creating custom UI for updater screen for native AIR applications (from blogpost) [...]

  4. Hi Piotr, thanks a bunch for this lib, do you know if there is any issue with AIR 2.5?

    Tiago Dias

    4 Jan 11 at 1:05 am

  5. I don’t know of any reason why it shouldn’t work with 2.5.
    p.

    Piotr Walczyszyn

    4 Jan 11 at 10:26 am

  6. Hi Piotr, is there any example of this updater in javascript? THanks for your contribution..

    zay

    19 Jan 11 at 2:39 am

  7. I’m using this code to provide an updater UI for my app but am not able to get the progressbar to update. The updater works, but the download always says 0% and the progressbar never advances. Any ideas?

    BTW I’m using Air 2.5

    Abram

    31 Jan 11 at 8:03 pm

  8. [...] You can also find out more about NativeApplicationUpdater here. [...]

  9. Good evening,
    thank you for this very good API. I have a problem some of my customers have installed a version with extension. exe and another. air. the update does not work with. air is there a solution other than to make them completely reinstall?
    thank you
    Best Regard

    aliong

    22 Mar 11 at 9:55 pm

  10. @aliong in that case there is no solution or at least I don’t know one, sorry ;)
    p.

    Piotr Walczyszyn

    23 Mar 11 at 8:57 am

  11. Hi Piotr, I’ve been using the updater. And everything seems to work fine on Mac OSX. However on Windows 7, after the app finishes downloading, the installer displays an error after clicking to replace the app. The pre-existing app is destroyed and there’s no update. I’m experiencing this is AIR 2.6.

    I noticed that if I put a file in the app’s folder then the replacement installation works fine. I was looking for a way to do that programmatically, but Windows fails to write the file in the application directory and the reference docs say this is a bad practice.

    Do you have any idea why the replacement installation would fail?

    Thanks, Don.

    Don-Duong Quach

    17 May 11 at 5:24 pm

  12. It doesn’t look like it’s a problem with the updater, but with the AIR installer / Windows 7/ my system. I tried the update on another windows 7 system, and it worked fine.

    Don-Duong Quach

    18 May 11 at 3:58 am

  13. I tried your NAU lib but when i run checkNow() the error shows as the update package is not mentioned as well as when i debug i got that there is non updateVersion also.
    what am i missing here.

    Any help would be appreciated.
    thnks in advance

    hector

    7 Jun 11 at 10:32 am

  14. n also i can see the update.xml file in debug so i the API has downloaded the file but it does not pick up the update package path. i m running a local server!

    hector

    8 Jun 11 at 6:52 am

  15. First off, thanks Piotr so much for this!!

    I had a problem when trying to use the demo app and SWC library which I wanted to share with the community – I solved the problem, but I’m not sure if it is the proper solution (Piotr you’d be the best judge of that).

    PROBLEM:
    When trying to get the Native Application Updater custom UI demo code to run, I experienced the following problem. After installing the app on my desktop, I clicked the “Check for updates” button, and an error dialog is shown:

    “Update package is not defined for current installerType: exe”
    …with OK button

    When I click OK it just returns me to the screen with the “Check for updates” button, and therefore the update didn’t work.

    I’m using the NativeApplicationUpdater-0.5.1.swc version of the library, with the latest version of the demo code, with the AIR v2.6 runtime, running on a Windows XP Pro box.

    SOLUTION:
    I downloaded the code for the NativeApplicationUpdater-0.5.1.swc version of the library and made the following change in line 232:
    - updatePackageURL = updateDescriptor.UPDATE_XMLNS_1_0::urls.UPDATE_XMLNS_1_1::[installerType];
    + updatePackageURL = updateDescriptor.UPDATE_XMLNS_1_0::urls.UPDATE_XMLNS_1_0::[installerType];

    I assumed that it was a typo that UPDATE_XMLNS_1_1 was used instead of UPDATE_XMLNS_1_0 in this line.
    After rebuilding the SWC and the demo app, it ran fine! Thanks again!

    kbobash

    23 Jun 11 at 9:25 pm

  16. Big thanks for this lib! I made a tweak as well to reset the internal state if the update check fails. I added:
    currentState = READY;
    after line 248

    Lavon

    24 Jul 11 at 10:36 am

Leave a Reply