Swiz 1.0 Review

I have listed some of the popular features and basic differences between Swiz 0.6.2 and Swiz 1.0.0 RC1 and supplied some resources below:

Although the swc file size has grown from 28K to 66K, Swiz still provides punch-packing architecture conveniences that border on alchemy.

Swiz Config

The configuration has been simplified and improved:

<fx:Declarations>
<swiz:Swiz id="mySwiz">
<swiz:config>
<swiz:SwizConfig id="mySwizConfig"
eventPackages="com.package.events"
viewPackages="com.package.views"
defaultFaultHandler="{genericFault}"/>
</swiz:config>
<swiz:beanProviders>
<config:Beans/>
</swiz:beanProviders>
</swiz:Swiz>
</fx:Declarations>

You can now declare your eventPackages and viewPackages paths.

eventPackages – If you point eventPackages=’com.package.events’, then you can simply reference any event in that package with Class.CONSTANT in the Mediate’s “event” attribute. This allows you to set the actual string value in your Event Class to what ever you want.
Mediator looks like this: [Mediate( event=”MyEvent.SUBMIT”)]
Event constant can look like this: public static const MyEvent.SUBMIT:String = ‘whateva’;

viewPackages – This is an option but will speed up the processing of the display classes.

Beans File

The Beans file looks similar but now is wrapped in a BeanProvider tag:

<swiz:BeanProvider xmlns:swiz="http://swiz.swizframework.org"
xmlns:controller="com.jci.h2o.controllers.*"
xmlns:delegates="com.jci.h2o.delegates.*">
<fx:Declarations>
<controller:MyController id="myController" />
<delegates:MockDelegate id="mockDelegate" />
</fx:Declarations>
</swiz:BeanProvider>

Swiz Events

[Dispatcher]
public var dispatcher : IEventDispatcher;

  • No longer do you use Swiz.dispatchEvent instead create a [Dispatcher] and call dispatcher.dispatchEvent and dispatch a standard Flex Event (yay!)
  • On Event Classes that are to be dispatched by Swiz, set bubbles=true so that the event will bubble up the display list, allowing Swiz to listen
  • [Dispatch] allows you to “technically” dispatch events from non-visual components ( somehow it’s always worked with 0.6.4 although it was not supposed to ).

Dependency Injection

  • [Autowire] metadata is no longer used to inject dependencies – instead use [Inject]
  • Inject any individual property of a Bean by specifying the source. ( Injecting an entire bean (or Injection by Name) using the “source” attribute has been available for some time however, I believe Injection of bean properties is new ).

Injection by Type

[Inject]
public var userService : UserService;    // Injection by Type

– or –

Injection by Name

[Bindable]
[Inject( source="userController" )]    // Injection by Name

– or –

Injection by property

[Bindable]
[Inject( source="userController.currentUser" )]    // Injection by property

Two way Binding

Very cool. Two way binding is supported via the Inject’s twoWay attribute.

[Bindable]
[Inject( source="userModel.currentUser", twoWay="true" )]
public var currentUser:User;

Mediate Multiple Events from a Single Method

Booyah!!

[Mediate( event="UserEvent.ADD_USER", properties="user" )]
[Mediate( event="UserEvent.EDIT_USER", properties="user" )]
[Mediate( event="UserEvent.DELETE_USER", properties="user" )]
public function mediateUserEvents( user:User ):void
{
// do stuff
}

– or –

[Mediate( event="UserEvent.*", properties="user" )]
public function mediateUserEvents( user:User ):void
{
  // do stuff
}

Service Helper

Service Helper is similar to AbstractController, however there is a really cool feature where you can pass an array of parameters that are then passed to your result handler eliminating the need to create an extra private var to hold the value from the service caller method over to the result handler.

public function fetchUserRoles( user:User ):void
{
sh.executeServiceCall( ro.getUserRoles( user.id ), getUserRoles_result, getUserRoles_fault, [ user ] );
}
protected function fetchUserRoles_result( data:Object, user:User ):void
{
user.roles = data.result;
}

Post Construct

[PostConstruct] methods are invoked after all dependencies are injected – for example – setting up a default user after the bean is created.

[PostConstruct]
public function createDefaultUser() : void
{
currentUser = new User();
}

Resources

New Swiz Website:
http://swizframework.org

The Swiz wiki is very well done. I suggest reading the entire user guide on the wiki:
http://swizframework.jira.com/wiki/display/SWIZ/Home

Brian Kotek has put together a nice demo to explore the new features of Swiz here:
http://swizframework.jira.com/wiki/display/SWIZ/Quick+Start

Michael Schmalle has gone a little deeper here:
http://blog.teotigraphix.com/2010/05/21/flex-swiz-1-0rc-demo-under-the-hood/

Adobe AIR Error 104 and 105 FileType

I have discovered that most AIR ‘Build Project’ errors are related to a malformed yourapp-app.xml file. Such is the case with the 105 Error of the FileType variety.

Error 105

I created an AIR app that would support my own File Type extension (mime type). In the fileType’s ‘name’ node, I put ‘My Custom App’. Seemed reasonable since the template comments stated ‘The name that the system displays for the registered file type. Required.

Turns out that the ‘name’ needs to be space-free and separated by dots:

<name>My.Custom.App</name>

Error 104

In the case of the 104 Error, I uncommented the ‘contentType’ and entered the mime type (which was text/xml in my case).

<contenttype>text/xml</contenttype>

Hope this saves someone some time and aggravation.

Flex CSS LinkBar ToggleButtonBar Selected Text Color

Wouldn’t any reasonable coding human assume textSelectedColor to be the color of the text of the selected button in a Flex LinkBar or ToggleButtonBar?

After trying every possible ‘selected’ or ‘active’ CSS tag know to man (actually to Flex), and tracking down every possible path of  inheritance, I embraced one of my coding standards: counter-intuitive measures often prevail over reasonable assumptions.

To my dismay, disabledColor was the ticket. It has nothing to do with the selected state and unlike textRolloverColor and textSelectedColor, it has no mention of ‘text’!

So if I had been smart enough to assume that a selected button is actually disabled, I would have been fine. So when you want to dress up your selected button in your LinkBar/ToggleButtonBar with all kinds of nice-nices, just remember that LinkBar and ToggleButtonBar buttons operate like politicians – just because you’ve been selected does not imply that you’re enabled.

LinkButton
{
textRollOverColor: #006699;
textSelectedColor: #003366;
/* Yes, this one controls the selected button's text color */
disabledColor: #0099cc;

/*Use DownSkin for Disabled to simulate Active/Selected Button */
disabledSkin: Embed(source="theme1.swf", symbol="LinkButton_downSkin");
downSkin: Embed(source="theme1.swf", symbol="LinkButton_downSkin");
overSkin: Embed(source="theme1.swf", symbol="LinkButton_overSkin");
upSkin: Embed(source="theme1.swf", symbol="LinkButton_upSkin");
font-size: 14;
font-weight: bold;
}

Adobe Air Updater error 16824

Trying to do a quick test of the Adobe AIR Updater feature, I ran into Error# 16284 immediately after the download of the update air file.

Adobe AIR Updater Download Error 16824

A quick google search presented me with the following description:

16824 Invalid update descriptor. subErrorID may provide more information.

Although vague, it did lead me to the solution. In my haste to test the updater, I simply copied and pasted the  app_1.0.air file and renamed it to app_1.1. Then I set the updater.xml file’s <version> tag to ‘1.1’ pointed the <url> tag to the new ‘app_1.1.air’ file.

The problem occurs when AIR downloads the app_1.1.air file and inspects the <version> tag in it’s app-app.xml file. AIR did not like the fact that version number still remained at ‘1’ when it was looking for ‘1.1’.  A quick update to 1.1 in the version tag, and upload the new build and problem solved.

If I didn’t want to create a new build, I could have simply renamed app_1.1.air to app_1.1.zip, open the zip file, edit the app-app.xml file and named the file back to app_1.1.air.

Chalk it up to another copy and paste error of a different kind. I hope this saves someone a little time.