Learning Flex – Lesson 21, Deploying Flex Applications

Adobe Integrated Runtime (AIR) allows you to write Flex applications that can be run from the desktop. AIR gives you access to features that are not available when running from the browser such as interaction with the local file system, an embedded database for client side storage and with the new AIR 2 beta , raw microphone data access and multitouch support amongst other things.

The basics of working with AIR are very similar to Flex applications. In Flex Builder or FlashDevelop, choose a new AIR project and instead of a root <mx:Application> tag, use <mx:WindowedApplication>.

In defining your application, the application id is important as this is used to register the app with the operating system so it needs to be unique. This value (along with other configuration data) is stored in the project’s application.xml file. Flex Builder allows you to specify the application id on project creation but FlashDevelop will default it to the project name so you’ll probably want to go in and change that. Further information on the application.xml file can be found here.

Because of the additional access they have, AIR apps need to be signed by a security certificate before they can be released.

You can create a self-signed cert or buy one from a certificate authority such as VeriSign (currently $499 per year) or Thawte (currently $299 per year). Note these are different to standard SSL certificates.

The downside to a self-signed cert is that the install screen will show a big red “?” along with the text “are you sure you want to install this application to your computer?” instead of the happy green “!” that you get with a valid paid certificate. You can find out more about how to get and install a certificate in this article.

FlashDevelop provides two batch files and an AIR_readme.txt file when it creates an AIR project to help you release your application. You can find out more information on packaging an AIR file (including potential error messages) in this article.

Advertisements

Learning Flex – Lesson 20, Creating Modular Applications

As your application gets larger, it could result in a pretty bulky swf that will take a long time to download and potentially cause users to get code for things they never use. There are also issues around re-using your code in different applications – if you just copy the source, it’s going to be a pain to maintain when you have bug fixes or enhancements for it.

Fortunately, there are ways to break up your code in Flex to reduce some of these issues.

Modules

Flex modules allow you to create a subset of code that can be loaded/removed at run time.  Say you’ve got an application that has features that only certain users have access to. You could provide the core of the app as your swf and then download the “special” functionality after a user of the correct type has logged in and asked to access that area. This saves everyone having to download code they may never  be able to access.

First of all you need to define your Module. The <mx:Module> tag defines the root of a module and you may have more than one of them in an application. It has a layout property that can be set to absolute, horizontal or vertical. More than likely, you’ll convert a current UI container class into a module so you can replace it’s tags with the Module ones.

FlexBuilder has functionality to aid with modules but if you’re using FlashDevelop, you’re going to have to do things a little differently. This post explains how to do that. Basically, you can specify compiler properties in an annotated comment (remember to do this within the <mx:Script> block if you’re Module is defined in MXML). The only addition I would make is to use the -source-path option to define the root of your source code so the compiler can find everything it needs to compile the module if you’ve got multiple folders within your source code.

The ModuleLoader class is a type of container that knows how to load and unload modules. As it’s a container, it can be added directly to the UI. It has a url attribute which specifies where to find the module swf at run time and can be given width and height attributes along with an id. The ready event is fired when the module is loaded and the object data of the module is available through the child property. The unloadModule() method can be used to remove the module.

A sample moduleLoader tag might look like this:

<mx:moduleLoader id="myModule" url="modules/myModule.swf" width="100%" height="100%" ready="handleModuleReady(event)"/>

In which case to set a property within my module I would cast the child to the module class to access the property like so:  MyModule(myModule.child).property=value;

You can also specify an error event handler to deal with problems trying to load your module. If you see an error something like this:

Error #1053: Illegal override of FlexModuleFactory in mx.core.FlexModuleFactory

Make sure you’re using the same  version of the Flex sdk for your module and your application (particularly if you’re using the FlashDevelop method covered above and you’ve got a project specific compiler specified – remember compiling the module with CTRL-F8 uses the default compiler).

Runtime Shared Libraries (RSL)

If you have common code that gets used between several of your applications, you can separate this out into a library and then either compile that in to each application or use it as an RSL. These can be cached on the client so it does not need to be downloaded every time the application is used.

It’s important to consider the size implications of using libraries – if you create ones that try to fit in too much, the overall size of your application at run time will go up as it will be including code from the shared library that it never uses.

Adobe has developed  special RSLs of the framework, data visualization and  data services classes so that they can be cached by the Flash player and any swf can use them, thus removing the need to compile in extra code and reduce the size of all apps. Thse special RSLs are digitally signed and have a .swz extension to ensure that only Adobe certified code is used.  They can be found in your SDK’s frameworks\rsls directory. Only Flash Player 9.0.115 and later can use the signed swz versions but there are swf versions available too.

To specify you wish to use  RSLs, you use the compiler -runtime-shared-library-path option. This is followed by the library file (swc) to compile against, the runtime location of the primary RSL (the swz), a policy file if needed (if this is your own unsigned RSL and you’re using it for a different domain) and the failover RSL (swf) runtime location for older Flash Players.

Here’s an example from my project:

-runtime-shared-library-path=C:\flex3sdk\frameworks\libs\framework.swc,framework_3.4.0.9271.swz,,framework_3.4.0.9271.swf

(I’m putting the framework RSLs in the same place as my application swf).

Creating a Flex Library

FlexBuilder has built in support for creating a Flex library (swc) file but for FlashDevelop you’ll need to use the command line compc compiler (there is a plugin for FlashDevelop but I couldn’t get it to work for me).

The best way to do this if you have several items is via a n xml configuration file.

You can then go to the bin directory under your SDK and run the command:

compc -load-config+=config-file.xml the += means in addition to the default config which makes sure you get access to relevant libraries.  Here’s an example configuration file:

<?xml version="1.0"?>
<flex-config xmlns="http://www.adobe.com/2006/flex-config">
  <output>C:\tools\flex\FlexGrocerLibrary\.\bin\FlexGrocerLibrary.swc</output>
  <use-network>true</use-network>
  <target-player>10</target-player>
  <warnings>true</warnings>
  <benchmark>false</benchmark>
  <compiler>
    <accessible>false</accessible>
    <allow-source-path-overlap>false</allow-source-path-overlap>
    <optimize>true</optimize>
    <strict>true</strict>
    <es>false</es>
    <show-actionscript-warnings>true</show-actionscript-warnings>
    <show-binding-warnings>true</show-binding-warnings>
    <show-unused-type-selector-warnings>true</show-unused-type-selector-warnings>
    <use-resource-bundle-metadata>true</use-resource-bundle-metadata>
    <verbose-stacktraces>false</verbose-stacktraces>
    <source-path>
      <path-element>c:\tools\flex\flexgrocerlibrary\src</path-element>
    </source-path>
    <external-library-path append="true">
      <path-element>C:\tools\flex_sdk_3.4\frameworks\libs\framework.swc</path-element>
      <path-element>C:\tools\flex_sdk_3.4\frameworks\libs\datavisualization.swc</path-element>
    </external-library-path>
  </compiler>
  <include-classes>
    <class>events.CategoryEvent</class>
    <class>events.ObjectDataEvent</class>
    <class>utils.Util</class>
    <class>valueObjects.Category</class>
    <class>views.MaxRestorePanel</class>
    <class>views.dashboard.ChartPod</class>
    <class>views.dashboard.ComparisonChart</class>
    <class>views.dashboard.SalesChart</class>
    <class>views.dashboard.TypeChart</class>
  </include-classes>
 <include-file>
    <name>downArrow.gif</name>
    <path>C:\tools\flex\FlexGrocerLibrary\src\assets\downArrow.gif</path>
</include-file>
<include-file>
    <name>upArrow.gif</name>
    <path>C:\tools\flex\FlexGrocerLibrary\src\assets\upArrow.gif</path>
</include-file>
 </flex-config>

Note the external library path entries for the framework libraries I’m referencing – the append attribute is to make sure these get added to any other libraries required. Make sure you specify these as external libraries rather than just libraries or they’ll get compiled in rather than just referenced.

Note also you can specify classes and asset files for inclusion.

Once this is run, you’ll have a swc file you can include as a library to your apps. To make it an RSL takes a little more work.  First of all, you need to extract the swf file from the swc using winzip or something similar, then you need to optimize it to remove debug information etc (you don’t need to do this if you’re building in your swc file as the compiler takes care of stripping that out when you generate a release build). You can find out how to optimize your RSL swf here.

Learning Flex – Lesson 16, Customizing the Look & Feel of a Flex Application

I’ve written a couple of posts previously looking at some aspects of this lesson but this a more detailed exploration.

There are two key ways to change the appearance of a Flex app – styles and skins.

Style properties allow you to change such elements as font size, background color and text alignment. Skins are graphical elements (either provided as files or created with ActionScript) that change the appearance of a component (eg button shape).

Applying Styles

Flex styles are based on the web standard CSS (Cascading Style Sheets). There are several levels a style may be applied at:

You may specify a single style on a particular component, use a CSS Class selector to set several styles together or use a type selector to specify that all components of a particular type should use the provided style values.

A style may be applied to a component directly in its MXML definition by adding the style name as a property and specifying it’s value such as

<mx:Label id="mLabel" text="My Label" fontWeight="bold"/>

to display a bold label. The setStyle() method can also be used to achieve the same effect – mLabel.setStyle("fontWeight","bold")

Note that when using setStyle() and specifying colors, the prefix 0x is used to indicate a hexadecimal value (and quotes are not required around them). When specified in a tag or CSS attribute, the prefix # may be used instead.

setStyle() is an expensive run time operation so it’s use should be limited.

The Flex language reference will tell you what styles are available for a particular component and will also specify CSS inheritance. If yes, this indicates that if the parent of this component has a value specified for the style, the child component will use the same value unless it has its own value specified. (For example, if you have a Label in a HBox, it will inherit the HBox color (text color) unless it has its own color value set.

Setting Styles with CSS

The <mx:Style> tag can be used to define local styles using CSS based syntax. Flex supports CSS class selectors which define a set of properties as a single class that can then be used by specifying the class name for a component’s styleName property.

<mx:Style>
.myStyle{
color:#FF00FF
selectionColor:#00FF00
}
</mx:Style>

<mx:ComboBox styleName=”myStyle”/>

You may also use CSS type selectors which define a set of styles to be applied to all instances of a component type.

<mx:Style>
ComboBox{
color:#FF00FF
selectionColor:#00FF00
}
</mx:Style>

<mx:ComboBox id="myBox1"/>
<mx:ComboBox id="myBox2"/>

Both myBox1 and myBox2 will have the same color and selectionColor.

Note that Flex does not support ID selectors.

Flex will support traditional CSS style formatting for the properties it supports (ie all lowercase with hyphen to separate words such as background-color) within a Style tag but for attributes that are specific to Flex and all attributes outside of Style tags, the camel case form of the name is required (eg backgroundColor). This is because the hyphen is not a valid character for XML attributes and MXML tags must be valid XML.

CSS properties that require multiple values are specified using a comma separated list of values. It’s important to note that those properties must have at least two values (even if they are the same) to avoid an error as a single value will not map correctly to an array.

You may also use mx:Style to specify an external CSS file to compile into the app using the source attribute. This should always be placed within the file containing the Application tag  – setting style imports in child documents can give rise to unexpected results.

Run Time CSS

The disadvantage of specifying an external file to load in this way is that it is compiled into the application and thus any changes to the CSS require the app to be re-compiled. By loading the CSS at run time, this situation can be avoided and different CSS files could be loaded depending on data provided so if for example, you had a collage sports app, you could brand your app with the team colors of where your users login from.

Flex can’t deal directly with a CSS file but the compiler can convert that to a SWF which it can use. To do this in FlashDevelop, right click the CSS file, select “always compile”, go to project properties and specify the output filename you want to use and compile (don’t forget to switch back to your regular app when you’re done).

Once you have your CSS SWF, just use

StyleManager.loadStyleDeclarations("myCSSFile.swf")

to load it. A second optional parameter is update a boolean (which defaults to true). If set, this forces an update of all the styles in the application. If you’re loading several CSS SWF files, you should set this to false for all but the last one to reduce the overhead of this operation.

you may also use

StyleManager.unloadStyleDeclarations("myCSSFile.swf")

to unload a CSS. This also has an optional update parameter with the same effect.

It’s possible to have several levels of style in play, the rule being that if a style is defined in multiple places, the last one loaded is the one used.

Learning Flex – Lesson 15, Implementing History Management

Using history management, a user can navigate through an application using the browsers back and forward operations as they would at a regular website.

Flex automatically supports this behavior for any navigation container. The property used to specify this is the boolean historyManagementEnabled. It’s true by default for Accordion and TabNavigator but false for ViewStack.

It works by saving the state of navigation as the user moves within the app (note only the container state is saved, not that of any components within it) and when the browsers back or forward buttons are selected, the HistoryManager loads the relevant state.

History management uses an invisible HTML frame into the browser window. The state of the container is encoded into the URL parameters for this frame. A javascript called history.js located in this frame decodes the parameters and sends the relevant information to the HistoryManager class in Flex.

By default, Flex Builder will create a HTML template for a swf with history management capabilities, Flash Develop will not. You can manually edit the created HTML file using the templates found under your SDK \templates\html-templates directory. If you want to change this default behavior, copy one of the templates from your SDK to your Flash Develop \projects\140 ActionScript 3 - Flex 3 Project\bin directory.

Note that history management will not work in IE when running a Flex app from a local file due to security constraints. It will work once deployed to a server and Firefox will show the correct behavior in both cases.

History management can be added to any custom component by following the steps below:

  • specify the custom component implements IHistoryManagerClient
  • implement loadState(), saveState() and toString() to satisfy the interface
  • call the static methods of the HistoryManager class to register() the custom component and save() when the navigation state changes.

To specify a class implements an interface in ActionScript, you would add implements interface (where interface is the interface class name) to the end of your custom class name definition eg public class MyClass implements IHistoryManagerClient. In MXML, you add an implements attribute to the end of your container tag eg <mx:HorizontalList ... implements="IHistoryManagerClient">

On creation complete, you should use HistoryManager.register(this) to register the component. At this point you must also call HistoryManager.save() to initialize the state.

If the component is a subclass of UIComponent, it will already have a toString() method. The saveState() method should return an Object that contains name,value pairs that represent the navigation state. As the URL size is limited, this data should be kept to a minimum. You would normally save something like the selected index for the container.

The loadState(state:Object) method is activated when the user clicks the forward or back buttons on the browser. The history manager passes in the Object created by the saveState() method for the container to use in deciding what navigation state to display. This object should be checked for null in case the user clicks the back button when there is no history to go back to.

HistoryManager.Save() should be called any time the component changes it’s navigation state so the history manager can keep track of what state the component is in.

Learning Flex – Lesson 5, Part II

Building Custom ActionScript Classes

Building an application in MXML results in an ActionScript class. The MXML is converted to ActionScript, combined with any code within a Script tag and the resulting class is compiled into a swf. When you compile test.mxml, a file named test-generated.as is created with the line

public class Test extends mx.core.Application

If you want to see the generated as files, add -keep-generated-actionscript to the flex compiler arguments. In FlashDevelop, you can do this by selecting project,properties… and clicking the compiler options tab. Click on the + next to the Additional Compiler Options and enter the value in the column to the right of [0].

Value or Data Transfer Objects

This kind of object is implemented as an ActionScript class and can be considered a container for data. They are often used for transfer of information to the back end of an application (potentially a database).

Each class is defined within a package similarly to Java. In fact, ActionScript classes look very similar to Java classes. One of the differences is how variables are declared ( var variableName:type; rather than Type variableName; ).

The [Bindable] metadata tag specified before a class name means that all public properties in the class can be bound to controls or other data structures. This can be placed before individual properties to limit it’s scope.

Externalizing Model Data

You can read the data for a model from an XML file by specifying the source property as the location of the file. The data will then be automatically parsed into an ActionScript compatible data structure. Data retrieved from a model tag is untyped so non strings must be cast to their type before use.

Debugging with Trace Statements

Flex has a global method called trace() that allows you to output data to the console when running the debugger version of the Flash player. It takes a string as the value and outputs the current value to the console. Defining a toString():String function within a custom class allows trace statements to automatically call this function if an object of that class is provided in a trace statement.

Using FlashDevelop

I’ve started using FlashDevelop since my Flex Builder trial ran out and so far, I like what I see. Here’s a basic intro on how to set it up.

First you’ll need to download it from the FlashDevelop site. Next you’ll need a copy of the Flex SDK if you haven’t already got one, you can find it here

Once you have FlashDevelop installed, you’ll need to tell it where to find your SDK

From the menu bar, select tools, Program Settings… and then click on the AS3Context from the Plugins on the left. You should see something like the image below

settings2

Note the “Flex SDK location” at the bottom – type in the path to your SDK there and you’re ready to start

You can start a new project from the Start Page or from Project,New Project… on the menu bar. Select “Flex 3 Project” from the list of templates and give it a name and root directory

The Project View on the right will now show your project structure. You can click on src to see the default Main.mxml and double click on that to see it in the editor. You should see something like this

basicproject

Note the bin directory where your swf will end up after compilation and the lib directory for adding swc files like that used for Google Maps.

If you want to include library files, add them to the lib directory, right click on the file and click on “Add to Library” you should then see check mark by it. Once you’ve done that, you can click on “Options…” below that to decide how it’s included.

Once you’re done, select “Build Project” from the project menu or use the little gear looking thing from the toolbar. Just over from that, you can select debug or release build.

The output window will show you the results of the build command and once you have a successful build, you’ll have a swf file in your bin directory and an index.html which will run it from a web page. If you click on the “+” next to the swf, it will expand and show you classes and symbols that got compiled in. Here’s one I made earlier

swf expanded

Double click the swf and it will run in your flash player.

There are several other plugins available for FlashDevelop – ones I’m interested in are for building swc files and connecting with Java remote services. I haven’t installed them yet but I’ll write up what I find out.