Changing AIR application directories

I came across an interesting feature of AIR. I was experimenting with the -app.xml file params, and was playing with the installFolder value. As it turns out, if you build a release with one value and install it, then build another release with a different value and overwrite the original install, it still gets installed to the first value. Here’s the example:

This installs to c:\Program Files\iotashan\My Application\MyApp\

1
2
<filename>MyApp</filename>
<installFolder>iotashan/My Application</installFolder>

This normally would install to c:\Program Files\iotashan\MyApp\, but will install to the above original directory if you overwrite your installation.

1
2
<filename>MyApp</filename>
<installFolder>iotashan</installFolder>

The way to fix this is to uninstall the app and delete the leftover directories.

Comments

Big Fat iPhone SDK “gotcha”

So I had an idea for a great iPhone app that now appears will never happen.

Why, you ask? Because Apple wants to have super-strict control of the user experience. The problem is hidden in the documentation… A nice little limitation that gets but a paragraph mention.

The iPhone will only allow a single 3rd party application to run at a time, and they also disable the ability to run an app in the background. My idea required an app that would run whenever the phone was on. Guess if I wanted to do anything, I’ll have to jailbreak my iPhone after all.

How does this impact the average user? This means no (useful versions of) instant messangers, listeners for push-based services, rss notifications, or anything else that the user would like to happen when they’re not actively using the application. This more or less limits the iPhone SDK to games and a few business applications.

Comments

Shan’s Simple Examples: Keyboard shortcuts and TextInput

Someone on #flex asked about preventing text from appearing in a TextInput or TextArea, when the user is using a keyboard shortcut. After a little discussion, I came up with a working example. I decided to use shift-space to simplify things.

The first assumption is that you’re listening for keyboard shortcuts at the application level:

1
application.addEventListener(KeyboardEvent.KEY_UP,shortcutHandler);

Now, you’ve got your input box, and it’s listeners:

1
<mx:TextArea height="100%" width="95%" keyDown="shortcutPreprocess(event)" textInput="shortcutPreventer(event)"/>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
private function shortcutPreprocess(e:KeyboardEvent):void {
    if (e.shiftKey && e.keyCode == 32) {
        _isShiftSpace = true;
    } else {
        _isShiftSpace = false;
    }
}

private function shortcutPreventer(e:Event):void {
    if (_isShiftSpace) {
        e.stopImmediatePropagation();
        e.preventDefault();
    }
}

Note that I had to set a boolean in my shortcutPreprocess method, and then I check for the boolean in shortcutPreventer. The reason being is that the textInput event doesn’t pass in the KeyboardEvent in any way, so I don’t know if there was a key combo pressed.

Working example & source:
http://www.iotashan.com/examples/KeyboardShortcut/

Comments

Shan’s Simple Examples: Using an XML datasource with mx:ComboBox

Over the weekend I was writing a simple little app, and came across something that should have been trivial, but turned out to throw me for a loop momentarily. I needed to drive some data from XML instead of my tried-and-true ColdFusion components, and I realized I’d never done it before. So, here’s the example:

First off, you need to actually get the XML file using a HTTPService:

1
<mx:HTTPService id="sectionService" url="pet.xml" resultFormat="e4x" result="sectionResult(event)"/>

Looks simple enough, but to produce valid XML, I needed to have a root node around my other nodes:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?xml version="1.0" encoding="utf-8"?>
<varieties>
    <variety name="Standard"/>
    <variety name="Angora"/>
    <variety name="Satin"/>
    <variety name="Rex"/>
    <variety name="Texel"/>
    <variety name="Satin Texel"/>
    <variety name="Satin Rex"/>
    <variety name="Satin Angora"/>
    <variety name="Fuzzy"/>
    <variety name="Fuzzy Angora"/>
    <variety name="Fuzzy Hairless"/>
    <variety name="Fuzzy Hairless Angora"/>
    <variety name="Hairless"/>
</varieties>

Now, when I put this directly into a XMLList object, I got a ComboBox with one option… my entire XML packet. It took a few tries to realize that I needed to make the DataProvider only the “variety” nodes, and that was easy to do:

1
2
3
private function varietyResult(e:ResultEvent):void {
    varietyXML = XMLList(e.result.variety);
}

So, for everyone who likes to see the whole picture, like me, here’s the entire MXML code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" width="100%" height="100%" initialize="init()">
    <mx:HTTPService id="varietyService" url="varieties.xml" resultFormat="e4x" result="varietyResult(event)"/>
    <mx:Script>
        <![CDATA[
            import mx.rpc.events.ResultEvent;
           
            [Bindable] private var varietyXML:XMLList;
           
            private function init():void {
                varietyService.send();
            }
           
            private function varietyResult(e:ResultEvent):void {
                varietyXML = XMLList(e.result.variety);
            }
        ]]>
    </mx:Script>
    <mx:ComboBox id="variety" dataProvider="{varietyXML}" labelField="@name"/>
</mx:Application>
Comments