Archives for November 2009

Creating custom Flex metadata tags for easier XML parsing

Having recently used Swiz for a project I became interested in learning more about custom metadata tags in Flex. I'm sure most Flex developers are familar with [Bindable], [Embed], [Event], plus a few others, but using Swiz you get introduced to a new tag, [Autowire]. Autowire ... where the heck did that come from, it's certainly not a standard Flex metadata tag. Being intrigued I decided to do some research and figure out how one would go about creating their own metadata tags and how they could be used.

My search for metadata enlightenment landed here:
http://www.quietlyscheming.com/blog/2007/10/24/declarative-binding-and-handlers-through-custom-metadata-flex-demo/

http://demo.quietlyscheming.com/MetadataExample/MetadataExample.html

http://demo.quietlyscheming.com/MetadataExample/MetadataExample.zip

Perfect, Ely's demo provides a good understanding of how one can create and utlize the metadata tags. The good news is they are relatively easy to create, the bad news is you can't do some of the special 'compiler magic' that tags like [Bindable] and [Embed] do.

The basic idea is you create any tag you want, you just need to tell the compiler to keep it and then using reflection provided by the describeType util you can see which public properties/methods have been annotated with the custom metadata tag.

So in 3 simple steps you can create your own metadata tag for use in Flex:

Step 1: in the compiler options you need to tell the compiler to keep your new metadata tag, using this -keep-as3-metadata+=XML. Be sure to use the '+=' otherwise you lose the standard Flex metadata tags. In this case I have added a tag XML.

Step 2: Add your new tag into your AS3/MXML files. Depending on how you intend to use your metadata tag, you may just have the tag, like this [XML] or with some attributes like this [XML(node="name", cdata="true")], just depends on how you intend to use it, totally your call.

Step 3: Create a class that uses the flash.utils.describeType to find the properties annotated with your shiny new metadata tag and then do whatever you want with it. The describeType util returns a XML object describing the public properties/methods on the specified class.

Great, so how about a real world example.

While reading up on how to create the custom metadata tags I came across a really good post by Christophe Coenraets on creating and using metadata tags. He created an AIR app that accesses a SQLLite database. Instead of manually mapping out the relationships between value objects and tables and the neccessary queries he used the metadata tags to annotate value object properties with their corresponding database table columns. 

Christophe's sample gave me an idea on how to solve a problem that has bothered me for a long time, parsing XML into and out of value objects. Many of the projects I work on use REST services to pass XML data between a Flex client and the server. When the XML is received on the Flex side it needs to be converted into typed value objects in actionscript and correspondingly, when the data needs to be sent to the server, the value objects need to be converted into XML. 

Normally this involves creating a setXML and getXML function on any value object. You end up with something like this:

 public function setXML(xml:XML):void 
{
id = xml.@id;
name = xml.name;
phone = xml.phone;
}

public function getXML():XML
{
var xml:XML = <person>
<name>{name}</name>
<phone>{phone}</phone>
</person>;
xml.@id = id;
return xml;
}

With only a few properties it's not bad, but adding more properites means having to update the setXML and getXML each time. It becomes tedious when creating many value objects.

Using custom Flex metadata tags you could easily remove the need for creating and managing all the code for xml reading and writing in any value object. The metadata tag would need to annotate each property with whether it is an XML node or attribute and what it's name should be.

Now the value object class looks like this:

 package com.dgrigg.vo
{
import com.dgrigg.utils.XmlMetaParser;

[XML(node="person")]
public class PersonVO
{
[XML(attribute="id")]
public var id:int;

[XML(node="name", cdata="true")]
public var name:String;

[XML(node="phone")]
public var phone:String;

public function PersonVO()
{
}

public function setXML(xml:XML):void
{
XmlMetaParser.read(this, xml);
}

public function getXML():XML
{
return XmlMetaParser.write(this);
}

public function toString():String
{
return "[PersonVO id='" + id + "', name='"+ name +"', phone='"+ phone +"']";
}

}
}

You can see the getXML and setXML have now been reduced to one line each. The properties that I need to send and receive via XML have been annotated with a custom metadata tag [XML] and the class was also annotated to define what the root xml node name should be.

The XmlMetaParser class now does all the work of transposing data between xml and the value objects. At it's core the XmlMetaParser uses the flash.utils.describeType to retrieve the description of a class instance, including all metadata information. With that information it simply becomes a process of using the metadata info to read and write the data. 

Using E4X you can quickly find the metadata nodes and values for each anotated property. A simple statement like this does the trick xml.variable.metadata.(@name=="XML").arg.(@key==key), where key is either 'node' or 'attribute'.

 <variable name="id" type="int">  
<metadata name="XML">
<arg key="attribute" value="id"/>
</metadata>
</variable>
<variable name="name" type="String">
<metadata name="XML">
<arg key="node" value="name"/>
<arg key="cdata" value="true"/>
</metadata>
</variable>
<variable name="phone" type="String">
<metadata name="XML">
<arg key="node" value="phone"/>
</metadata>
</variable>

As you can see, creating a custom Flex metadata tag is an easy process and it's uses are as limitless as using Flex to create something.

You can download the XmlMetaParser and sample files here.

Update 12/30/2009: the source code has been updated to handle complex objects, read more here.

When to Flash and when to Flex

I received an email yesterday from my wireless/cable/home phone/internet company inviting me to take part in a customer appreciation online event. Click a link win a prize, sure why not. The first thing that greets me upon clicking the url is the 'out of the box' Flex preloader. Wow, beautiful, they really broke the bank on building this campaign. I guess since they used Flex there wil be a lot of forms to fill in, maybe some neat charts and graphs, must be more than your standard, run of the mill marketing campaign.

Ok, if you are building a Flex app, replace the standard preloader, it's easy. Look here, here, and here.

Wait for the preloader to finish, looking forward to seeing some neat Flex app they've built.

Oh man, I can't wait

Wow, this looks like something that could have been built in Flash. Maybe if I click the open button I'll get to the good stuff.

 

I won't bore you with more screen shots. That's it, that's the only Flex'ish screen in the entire application. One simple data entry form.

So my question is why? Why would Rogers, or more likely some outside agency, build this site using Flex? What possible benefit did they get by using Flex? The data transfer off the form is a simple HTTP POST, even something more exotic like AMF could just as easily be done in Flash. Maybe there are many forms, with lots of data validation etc to go through. Nope, just the one pictured above, and based on the look they went with, that could have been done just as easily in Flash, it's certainly not the standard Flex controls.

The entire swf is 2.3MB, the Flash framework likely accounts for 500KB of that, maybe more, so it's pretty heavy with images etc and leaving out the framework would not have saved that much download time. But seriously, why would a site like this be built in Flex? It makes no sense. Flex is for APPLICATIONS. Flash is for CREATIVE EXPERIENCES. You need to use the right tool for the job.

It is pure conjecture on my part, but I bet this took longer to build in Flex than it would have taken in Flash. It was more than likely built by someone new to Flex so they had a learning curve figuring out how to get this done. Flex developers, in my experience, are more expensive than Flash developers, mostly because of their scarcity, so Rogers likely paid more also, but hey, that's ok since it was technically partially my money, money that really could have been better spent on upgrading their technology.

IT people, interactive people, developers, project managers, and anyone else involved in the process of deciding whether to use Flash or Flex for a project really need to weigh the pros and cons of each and then make an informed decision. Don't just think that because you ultimately get a swf from either path they are the same, they are not. 

When to Flex:

  • mid to large applicatios
  • data heavy
  • charting, graphing data visualization requirements
  • modular development
  • lots of form input UI screens
  • not as concerned about final SWF size

 

When to Flash:

  • marketing, promotional, interactive sites
  • design heavy
  • highly customized UI
  • online games
  • animation
  • concerned about final SWF size

 

What about AIR? What about AIR ... you can wrap a Flash or Flex project in AIR. For that matter you can wrap an HTML/Javascript app in AIR.

Remember, Flex and Flash both ultimately boil down to the same thing. An AS3 based SWF. How they get there is slightly different and what they roll into the SWF is also quite different. Flex adds a lot of extra 'stuff' you may not actually need or fully benefit from, as is certainly the case in the Rogers site.