19
Apr

Designer and Developer workflow with Adobe Flash Catalyst

Comments Off on Designer and Developer workflow with Adobe Flash Catalyst

I’ve recently made a presentation during a Flash Camp, focused on Flash Catalyst, the new product in CS5.
Flash Catalyst is, the way I see it, a nice tool intended to enable designers the access to Flex SDK in order to create Flex Applications without any specific knowledge of programming or ActionScript.

Until know, only developers with Flex knowledge, speaking ActionScript language could shape a Flex Application, applying the look & feel provided by a visual designer. Unlike developers, designers don’t speak ActionScript. Instead, they speak Illustrator, Photoshop, Corel Draw, Flash, Fireworks, or the language of another tool out there. A designer would feel much more comfortable drawing a shape ressembling to a button rather than typing a code like

<s:Button id="submitButton" label="Submit" bottom="10" right="10" />

In this presentation my intention was not to advertise Catalyst, but rather to focus on the productivity aspects and what is the best way to use this tool to create RIAs.

Problem
Catalyst is a great tool to create prototypes of Flex Applications quite easy. Even though Catalyst is a powerful tool, sharing a project between Catalyst and Flash Builder, between a designer and a developer, is quite challenging. Once the prototype is signed off by the client and it needs to be implemented by developers, issues arise :

  • From a designer perspective, Catalyst feels great. Firstly, because Catalyst integrates well with Illustrator and Photoshop. If an effect is harder to create with Catalyst, a designer can always right click and choose to “Edit in Adobe Illustrator”. Besides that, the designer can easily add actions to objects and grasp a bit of the look&feel of the application.

    Problem is that, in a short while, designers will notice that there are few connections between their Catalyst project and the actual application, even though that application is built with the design they created in Catalyst. Before, all they had was Flash or Illustrator approach, creating only designs for how stuff looks. Now, even thought they have control over where the stuff is positioned, how it behaves, transitions, they’ll realize that they’re still away from the actual application. They create prototypes, but they’re still waiting for developers to implement their modifications.

    This feels better than before, but it’s not perfect.
  • From a developer perspective, things are not as great either. It’s hard to work with a machine generated code, thus it’s hard to work with the raw code generated by Catalyst. Sometimes, it’s hard even for humans to write code that humans can understand. Martin Fowler has a say: Any fool can write code that a computer can understand. Good programmers write code that humans can understand.

    So don’t expect Catalyst to grab an Adobe Illustrator file and turn it into a perfect MXML. A programmer will not be able to easily use the raw code generated by Catalyst; copy-paste might be the only way to grab the Visual Design and place it into Code, by scanning through the read-only Code-view exposed by Catalyst and getting the pieces that make sense for a developer, and place those pieces into skin files.

    Besides that, the FXP container, it’s a single file. As a programmer you want to keep you source files into a versioning file system, instead of a single file container.

    So now it’s indeed easier to get the complex shapes and shades that the designer creates, because they’re now available in FXG format, which Flex 4 can read. But still, things are not perfect since developers sill need to filter all that raw code generated by Flash Catayst, and only get the modifications they’re interested in.

Solution
Long story short: fix the issues mentioned. In other words:

  • For a designer:
    • Easily test the UI changes into the real application
    • And preview the real application straight from Catalyst
  • For a developer:
    • Use straight what Catalyst provides.No extra copy-paste from Catalyst into Flash Builder.
    • No more headakes to match the pixel perfect visual design
    • More focus on functionality, less focus on design

You can achieve all these with this first release of Catalyst, event though it’s not that straight forward.
I’m going to describe here a few things that helped me solve these issues for a current project. If you’re comfortable with Flash Catalyst, you can download the Catalyst project now to experience it, and then continue.

  • First, I added these 2 buttons in the Flash Catalyst project, to enable the designer to easily switch from Visual Design to the real application
    Catalyst toolbar
  • Then I placed these under a Catalyst layer, which I called it “Top Toolbar”.
    Top Toolbar
  • This next step represented the main challenge: how to manage both Flash Catalyst file and Flash Builder files.

    Flash Catalyst had all the code bundled into a FXP file, while the real project had modules, each module had a separate project, so the configuration differed quite a lot. As you can see, in the next image, in the right side I have 4 Flex projects, while in the left side, I have only the Flash Catalyst project

    The question is how to merge the two, in a way that is productive for both the developer and the designer.

    • The first solution that came to my mind would have been to duplicate the code base out of the 4 projects, and place that code into the Catalyst project. This solution wasn’t so nice because it could have generated a lot of duplicated code to be maintained.
    • The next solution I liked it better. I thought to myself why not take advantage of the modular structure, and instead of maintaining a lot of source code files, maintain only 1 file for each module, which is the compiled SWF file. This way, with only a few files added to the Catalyst project, the designer can have the entire application at hand.

      To achieve this I had to go through several steps ( only developers are required to do this. The designer shouldn’t even care as long as the visual design remains the same):

      1. With Flash Builder: Split the application in functional areas and compile each area into a flex module. These are the modules to be loaded when running the Catalyst Project. This step is important because developers need to think well what is functionality, and what is skin and skin-behavior. The functionality would eventually stay in the modules, while the skin and its behavior would be exposed through a Main.css file to the Flash Catalyst.
      2. With Flash Builder: Make the main application only a shell-like application which only loads modules and also loads a main skin file compiled as SWF, at runtime.
      3. With Flash Catalyst and Flash Builder: Isolate the skins and skins behavior into skin classes. Expose these skin classes through the CSS file.The Main.css file should be good enough to store all about how application looks and feels.
        @namespace s "library://ns.adobe.com/flex/spark";
        @namespace mx "library://ns.adobe.com/flex/mx"; 
         
        s|Application
        {
        	font-family: "Myriad Pro";
        	font-lookup:embeddedCFF;
        }
         
        @font-face
        {
        	fontFamily: "Myriad Pro";
        	src: url("/Users/dragos/Library/Fonts/MyriadPro-Regular.otf");
        	embedAsCFF: true;
        }
        .videoControlBar
        {
        	skinClass: ClassReference("skins.controlBar.VideoControlBarSkin");
        	horizontal-center: 0;
        	bottom: 15;
         
        	font-family: "Myriad Pro";
        	font-size: 9;
        	color: #CCCCCC;
        }
        .videoPlayer
        {
        	left:0;
        	right:0;
        	top:0;
        	bottom: 40;
        }

        As you can see, I even declared the position of the video player in the screen, so that the bottom part leaves a space for the control bar. If later, the designer comes back to this and wants to make the control-bar overlay with the video, I could set “bottom:0” for .videoPlayer and I can achieve this.

      4. With Flash Catalyst and Flash Builder: Create a configuration describing which modules to load into Catalyst. This will enable the designer to see the actual application, or maybe just a part of it. This is how I declared the modules:
        ...
        <fx:Declarations>
        <config:MediaCenterConfigurationDto id="defaultConfiguration">
        	<config:modules>
        		<s:ArrayCollection>
        			<config:MediaCenterModuleDto 
        			 label="Flex player" version="1.0" 
        			 fileName="assets/MediaCenterPlayer.swf" />
        			<config:MediaCenterModuleDto 
        			label="Flex control bar" version="1.0" 
        			 fileName="assets/MediaCenterControlBar.swf" />
        		</s:ArrayCollection>
        	</config:modules>
        </config:MediaCenterConfigurationDto>
        </fx:Declarations>
      5. With Flash Catalyst and Flash Builder: Update project’s Main.mxml file, adding the functionality to load modules.This can be achieved in several ways, you can see in the Catalyst project my approach.
      6. With Flash Catalyst and Flash Builder: Add the toolbar layer described above
      7. With Flash Catalyst and Flash Builder: Add the logic to show the actual application or hide it, to the buttons within the toolbar: “Show real application” or “Show design”

This is the setup I needed. So , to summarize, these are the points I have achieved at this moment:

  • As designer, I can preview the changes into the action application by running only the Flash Catalyst project
  • As developer, in order to update the visual design, I only need to compile the Main.css file into a SWF file and load it at runtime. No extra work needed.

If you’re wondering how did I manage to edit the Flash Catalyst files, since they are in read-only mode in Catalyst, I’m going to create a new post really soon and detail there how I managed to open an already opened Flash Catalyst project, into Flash Builder, and edit at the same time Flash Catalyst and Flash Builder.

For now, you can download the Catalyst project I used in this demo and play with it. At the same time, you can view also the PowerPoint presentation.

12
Apr

Avoid user’s cache when deploying new versions of Flex app

As to continue my previous post, these days I’ve been trying to provide a solution that removes the ambiguity for the released swf files into production so that I know what version is deployed and also to make sure that the users are forced to get the last release, no matter of their browser’s cache.

Problem
When deploying new versions of the application, some users having cache in their browser don’t see the updated version of the swf, thus loosing the updates.

Solution
Automatically append the version number at the end of the url pointing to the swf file, ending with something like : Main.swf?173-1.0-SNAPSHOT. The advantage is that you benefit of the cache in-between new releases; this means that clients can view you flash application faster, and only for new releases they have to wait a little bit more to load.

Having the flex application packaged inside of a WAR file I’ve been looking for places to store this information inside of it, and read the build-number at runtime. I discovered that the MANIFEST.MF file, which is found inside the META-INF folder, is the best candidate.
In order to write the buildNumber into that file, I used maven-war-plugin:

<plugin>
	<groupId>org.apache.maven.plugins</groupId>
	<artifactId>maven-war-plugin</artifactId>
	<version>2.1-beta-1</version>
	   <executions>
		   <execution>
		        <phase>package</phase>
		        <goals>
		          	<goal>war</goal>
		        </goals>
		        <configuration>
		           <archive>
	          		<manifest>
	          		   <addDefaultSpecificationEntries>
	   	   	   	      true
	   	   	   	   </addDefaultSpecificationEntries>
	          		   <addDefaultSpecificationEntries>
	   	   	   	      true
	   	   	   	   </addDefaultSpecificationEntries>
	          		</manifest>
		          	<manifestEntries>
		            	   <Implementation-Build>
	   	   	   	      ${BUILD_NUMBER}
	   	   	   	   </Implementation-Build>
		          	</manifestEntries>
		           </archive>  
		        </configuration>
		</execution>
	</executions>
 </plugin>

${BUILD_NUMBER} is only available when executing the maven build from Hudson, as explained in my previous post. Maven also has a plugin that generates a build number automatically, but I didn’t need it because, in my case, no code goes into production without passing the Continuous Integration build and the tests, so I will have a build number for every promoted build.

Next, I had to read the information at runtime. For that I altered a bit the index.jsp file I am using to show the flex application:

<%@ page language="java" pageEncoding="UTF-8" contentType="text/html;charset=utf-8" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
 
<% 
java.util.jar.Manifest manifest = new java.util.jar.Manifest();
manifest.read(pageContext.getServletContext().
                                   getResourceAsStream("/META-INF/MANIFEST.MF"));
java.util.jar.Attributes attributes = manifest.getMainAttributes();
String fullVersion = attributes.getValue("Implementation-Build") + 
                 "-" + attributes.getValue("Specification-Version");
%>
 
<c:set var="swf" value="bin/MediaCenter"/>
<c:set var="version" value="<%=fullVersion%>" />
 
<%@ include file="/flex.jsp" %>

The flex.jsp file is taken from the FNA project hosted on Google Code. I’ve only altered a bit just to add the version number at the end of the request:

swfobject.embedSWF(
            "${ctx}/${swf}.swf?${version}", 
            "${application}_div", 
            "${width}", "${height}", 
            "${version_major}", xiSwfUrlStr, 
            flashvars, params, attributes);

That’s pretty much it. The result is:

Main.swf?173-1.0-SNAPSHOT

and it’s set automatically, for each build. This ensures that users, testers, everyone else see the right version of the application.

Note that I’m also using the Specification-Version, which is the same with maven version. The reason I’m doing this is because locally, on the dev machine, the ${BUILD_NUMBER} is null, and I simply didn’t want to see Main.swf?null in the url :). Specification-Version came for free with the Maven-war-plugin, so I decided to make use of it. The MANIFEST.MF file contains more information; you can have a look into that file, after deploying it.

05
Apr

Automatically version a Flex application with Maven

Today I had an issue debugging a Flex application.

Problem

Some of my changes were not built correctly and I had a hard time debugging and checking whether the version of the swf I had deployed is the same with the latest version of my swf file.

Solution

I wanted to have an embedded code into the swf and display it into a label, at runtime. Browsing the internet initially, I’ve found some solutions using Python and Ruby.  Having my build in maven, I decided to see what is provided by Flex, FlexMojos and Maven in order to facilitate that.

Analyzing the mxmlc compiler arguments I have found that I can define custom parameters into the compiler and read them from actionscript code. So I have defined a BUILD::buildNumber compiler variable:

-define+=BUILD::buildNumber,"'1.0.0'"

In the Main.mxml application I’ve added:

<fx:Script>
	<![CDATA[
		[Bindable]
		/**
		* specified through the flex compiler arguments like: 
		* -define+=BUILD::buildNumber,"'1.0.0'"
		*/
		private static var buildNumber:String = BUILD::buildNumber;
	]]>
</fx:Script>		
<s:Label 
	right="0" top="0"
	color="red"
	text="{buildNumber}" />

Next, I had to change the compiler parameter for each build, automatically. Using Hudson as my Continuous Integration server, things got very simple. When a Hudson job executes, it sets some environment variables that can be used in build scripts. Among those variables there is BUILD_NUMBER.

<plugin>
       <groupId>org.sonatype.flexmojos</groupId>
       <artifactId>flexmojos-maven-plugin</artifactId>
       <version>${flex-mojos.version}</version>
       <extensions>true</extensions>
       <configuration>
                <definesDeclaration>
		 	<property>
		 	       <name>BUILD::buildNumber</name>
		 	       <value>"${BUILD_NUMBER}-${project.version}"</value>
		 	</property>
          	</definesDeclaration>
       </configuration>
</plugin>

The output of this, for a buildNumber 173 and a project version 1.0-SNAPSHOT is:

173-1.0-SNAPSHOT

The next thing I need to achieve, is to trick the browser’s cache, using this buildNumber, appending it at the end of the request for Main.swf, to end up automatically with a request like:
Main.swf?173-1.0-SNAPSHOT.

My next post covers this.