Archive for May, 2009

The importance of providing an update mechanism in an AIR application

Applications provide updates for many reasons, including bug fixes, security patches, and new functionality. This holds true for AIR applications as well.

Adobe ships occasional update versions of Adobe AIR. And Adobe AIR applications can take advantage of new features and bug fixes in new versions of the runtime.

Also, new versions of Adobe AIR may include updated versions of WebKit (the HTML rendering engine in AIR). This may change the behavior or appearance of HTML content in an AIR application. For example, improvements or corrections in WebKit may change the layout of HTML elements in an AIR application’s user interface.

It is important to provide an update mechanism in your application. When you update your application, the application can inform the user of the new update version. Should you need to update your application due to a change in the WebKit version included in AIR, the update mechanism will let your users know about the new version of your application.

AIR includes a update framework, which simplifies the task of managing update versions and adding appropriate user interface in your AIR application.

For more information, see “Updating AIR applications” in the AIR developer’s guides:

Also, these “Quick Start” sample applications show how to use the update framework:

DataProvider.getItemIndex()

A user recently asked why the call to DataProvider.getItemIndex() in the following example returns -1:

import fl.controls.List;
import fl.data.DataProvider;
var dp:DataProvider = new DataProvider();
dp.addItem({label:"AL", data:"Montgomery"});
dp.addItem({label:"AK", data:"Juneau"});
dp.addItem({label:"AR", data:"Little Rock"});
// assign the data provider to the list
var myList:List = new List();
myList.dataProvider = dp;
myList.rowHeight = 35;
myList.rowCount = dp.length;
myList.move(10, 10);
addChild(myList);	// display the list
// this attempt to locate an item in the list returns -1
trace("Index is: " + myList.dataProvider.getItemIndex({label:"AK", data:"Juneau"}));

Paul Robertson explains:

The problem is that the getItemIndex() method matches exact object references, not objects with matching properties. The first object, {label:”AK”, data”Juneau”}, may
have identical property values with the one that’s being passed to the getItemIndex() method, but they’re not exactly the same object – they’re just two different objects that happen to have the same property values.

To get a match with getItemIndex(), you need to pass a reference to the actual object that’s in the data provider. To do that, of course, you need a reference to the
same object, for example in a variable. Here’s a variation of your code that works:

import fl.controls.List;
import fl.data.DataProvider;
var dp:DataProvider = new DataProvider();
var item1:Object = {label:"AL", data:"Montgomery"};
var item2:Object = {label:"AK", data:"Juneau"};
var item3:Object = {label:"AR", data:"Little Rock"};
dp.addItem(item1);
dp.addItem(item2);
dp.addItem(item3);
var myList:List = new List();
myList.dataProvider = dp;
myList.rowHeight = 35;
myList.rowCount = dp.length;
myList.move(10, 10);
addChild(myList);
trace("Index is: " + myList.dataProvider.getItemIndex(item2));

Of course, you are probably really trying to do some sort of search to find the index of an item that matches a user entered string. The only way I can see to do that is to loop over the data provider one item at a time and compare the property values. You can either loop over the data provider directly using dp.length and
dp.getItemAt(index), or else keep the objects in a separate array. This code demonstrates the first approach:

import fl.controls.List;
import fl.controls.Button;
import fl.controls.TextInput;
import fl.data.DataProvider;
var dp:DataProvider = new DataProvider();
dp.addItem({label:"AL", data:"Montgomery"});
dp.addItem({label:"AK", data:"Juneau"});
dp.addItem({label:"AR", data:"Little Rock"});
var myList:List = new List();
myList.dataProvider = dp;
myList.rowHeight = 35;
myList.rowCount = dp.length;
myList.move(10, 35);
addChild(myList);
var ti:TextInput = new TextInput();
ti.width = 100;
ti.move(10, 10);
addChild(ti);
var btn:Button = new Button();
btn.width = 50;
btn.label = "Search";
btn.move(120, 10);
addChild(btn);
btn.addEventListener(MouseEvent.CLICK, btn_click);
function btn_click(event:Event):void
{
for (var i:int = 0, len:int = dp.length; i < len; i++)
{
if (dp.getItemAt(i).data == ti.text)
{
trace("Index is: " + i.toString());
return;
}
}
trace("Item not found");
}