Recently in Flex Category

I had a great time presenting at Flash Camp Philadelphia 2009.  My session was Using FlexUnit 4.  I covered the new features of FlexUnit 4 and dove into a lot of examples, from getting started with writing test cases to integrating FlexUnit test results into your Continuous Integration server via an ANT build process.

You can find the slides (exported with additional notes that I've since added for context) here: FlexUnit4.pdf

The example code to complement the slides is here: FlexUnit4Examples.zip  - Note, at the time of the presentation, these examples were compiled against the FlexUnit 4 "beta 2" drop.

Thank you to everyone who attended my session.  The questions at the end were great, and I enjoyed the interaction. Be sure to check out the FlexUnit 4 forums if you need additional support!

Mate vs. Swiz

| No Comments | No TrackBacks
Last week I gave an online presentation to a user group of Flash Platform developers in Boston.  The presentation was focused around the Mate and Swiz Flex frameworks.  Having experience using both, I wanted to highlight how the frameworks compare side-by-side.

I've exported my presentation slides into a PDF file (with the presenter notes view enabled).  You can download the slides here: http://www.darronschall.com/presentations/2009/10/08/Mate vs Swiz.pdf

The main theme of the presentation was that both frameworks are MVC frameworks for Flex.  No matter what framework you choose you should end up with similar architecture at a high level.  The key differences are really in the implementation details (and they're not as different as you might think).

The last slide offers some food for thought.  Which framework should you choose?  There is no easy answer.  This is largely a matter of personal preference, opinion, and style.  I've used both in applications and been happy with the results.  Some teams prefer Mate, some teams prefer Swiz.  One is not necessarily better than the other, they're just... different.  

As always, your mileage may vary.

A common design pattern used in Flex applications is leveraging mock delegates in the business layer.  Mock delegates and delegates share the same client/server interface, but the mock versions can be used as stand-ins for the real delegates when a connection to the server cannot be established or perhaps when the server method has not been built or is not integrated yet.

For example, if an application needs to log a user in it might make a call to LoginDelegate::login and pass along the user's credentials.  The server might respond with the detailed user information if the credentials are valid, or it might throw an error or return null of they are not.

Since a login screen is typically the first screen in an application, client-side development is generally dependent on the server's ability to log a user in consistently.  What happens when this isn't the case?  This is where mock delegates shine.  They free client-side developers from server-side dependencies and enable development to proceed even if the server or the remote method is unavailable.

Mate has Mock Services (pdf)  to enable easy mock delegate creation.  With Swiz you build mock delegates that leverage TestUtil.mockResult.  If you google for MockRemoteObject there are other implementations to be found out there, such as this one.

Once mock delegates have been created, populating them with fake data to return usually involves creating some code to generate random data. Something like this...

public function getUserList():ArrayCollection
{
    var users:Array = new Array();
    var user:User;
    
    // Generate 10 fake users
    for ( var i:int = 1; i <= 10; i++ )
    {
        user = new User();
        user.id = i;
        user.firstName = "First " + i;
        user.lastName = "Last" + i;
        // More here... Math.random(), lorem ipsum generation, etc.        

        users.push( user );
    }

    return new ArrayCollection( users );
}

There are more sophisticated tools you can use to generate mock data (this StackOverflow question is probably a good place to start looking), but the general idea of creating fake values and stuffing them into objects still applies.

Fortunately, this process can sometimes be made easier with ServiceCapture (or possibly Charles or another tool, but I'm a ServiceCapture user).

ServiceCapture is a developer tool that captures HTTP traffic on a computer. It enables the introspection of data being sent between the client and server tiers, and includes support for decoding AMF. It also has the ability to save responses received from the server.

That last line is important. With ServiceCapture, it is possible to locally save the response from a server (even AMF responses). These responses can then be used in the mock service layer to accurately simulate real responses in mock scenarios.

Naturally, this technique only works when the remote method is available to capture results from. If client and server development are happening in parallel and the server has not exposed any methods yet, the technique of using a server response as a base for a mock response does not apply. However, when server methods are available to test against, saving responses is both beneficial (since mock data behaves like real data will during development), and time saving (because scripting mock data becomes just a few lines of code).

Here are the steps to take in order to leverage a saved server response in a mock server method:

  1. With ServiceCapture open, make the appropriate call to the remote method from the client application. ServiceCapture will show the request as a line item in it's grid view.
  2. After the result comes back from the server, right-click on the call and select "Save Response" from the context menu.
  3. In the Save dialog, save the response to your local computer. A good practice here is to use the method name and parameters followed by an extension such as ".data" for AMF responses to indicate that the response is binary. For example, if the method is getUserDetails and takes a userId:int parameter, the saved response might be named getUserDetails_13.data.
  4. Place the saved .data file in the appropriate folder location in the project directory, e.g. Project/mock/[projectPackagePath]/services/data (where mock is defined as an additional source folder in the project properties).
  5. In the MockDelegate class, embed the .data file and read in the contents at runtime. Return the contents to the user as the mock result. An example:
    /**
     * This particular example would be used as a mockGenerator for a MockRemoteObject
     * in Mate.
     */
    public class MyServiceMock
    {
    	[Embed( source="data/getUserList.data", mimeType="application/octet-stream" )]
    	private var getUserListData:Class;
    		
    	public function getUserList():ArrayCollection
    	{
    		var response:ByteArrayAsset = ByteArrayAsset( new getUserListData() );
    		response.objectEncoding = ObjectEncoding.AMF3;
    		response.position = 30
    		var ackMessage:AcknowledgeMessage = response.readObject();
    		var collection:ArrayCollection = ArrayCollection( ackMessage.body );
    			
    		// At this point, collection is an ArrayCollection of User instances.  If
    		// we wanted to, we could change some properties here to "mock" more data, but 
    		// just returning the collection is exactly the same as what we would get from
    		// the real service.
    			
    		return collection;
    	}
    }
    

You'll notice that there's some special sauce in the code example above. The server response is created as a ByteArrayAsset, and then the position is moved to position 30 before reading the AcknowledgeMessage instance from it. The actual data being returned is contained in the message's body property.

The position of 30 is not consistent in every scenario and varies based on the server's response, but it usually works. I used a hex editor to determine the location to use to start reading this particular AMF remoting envelope's body response.

A better approach would be to create a small library to pull the response data out automatically. That said, however, this approach can still be a big time saver when it comes to generating mock data. Not only is it faster to create the mock data, but the data itself is a direct copy of real data for the system which gives the application a better feel during development and testing.

In summary, mock delegates enable parallel client/server development, simplify integration, and enable offline development.  By using a tool such as ServiceCapture, you can quickly and easily generate data in your mock services that exactly matches the data returned by the server.

Flash Camp Atlanta 2009

| No Comments | No TrackBacks

Where has this year gone? It's already August, which means Flash Camp Atlanta 2009 is right around the corner. If you're looking for a quick way to gain some insight into the Flash Platform and learn some new tricks, Flash Camp is a great one-day conference with a talented speaker lineup.

The speaker lineup includes a keynote from Greg Wilson of Adobe, with sessions presented by David Tucker, Jesse Warden, Carl Smith, Leif Wells, Douglas Knudsen, Ben Stucki, and Christian Saylor. All of the sessions share a common theme: "Enabling the Convergence of Art & Science With The Flash Platform."

The full-day event is happening on Friday August 28th at the GeorgiaWorld Congress Center in downtown Atlanta. If you haven't signed up yet, this is a great opportunity to get together with fellow professionals and learn a thing or two about the craft. It's a little too late for the early bird pricing, but the tickets are still reasonably priced for a one-day conference packed with content.

For some additional information, here's what a few other people have to say around the blogosphere: Doug Knudsen, Russell Brown, and David Tucker.

Disclaimer: I'm employed by Universal Mind, an elite group of technologists who excel at solving the difficult challenges of building an optimizing rich internet applications, and also the primary sponsor of Flash Camp Atlanta 2009.

DelegateInvoker for the Mate Flex Framework

| No Comments | No TrackBacks

I've been using the Mate Flex Framework a lot in recent history.   I think it's a solid framework that does a lot of things right and it's very lightweight and easy to use.  If you haven't used it yet, it's at least worth looking into.

That said, I was recently confronted with a situation in which the current service invokers were insufficient.  By service invokers, I mean specifically the RemoteObjectInvoker, HTTPServiceInvoker, and WebServiceInvoker classes.  Let me explain.

When you use the Web Service code generation tools from FlexBuilder Gumbo MAX Preview, you end up with a service class that wraps a web service and provides a well defined public interface.  Each method in the class returns an AsyncToken that allows you to add a responder to be notified of success/failure when the remote method call comes back.  The generated code looks something like this:

public class MyService extends WebServiceWrapper
{
    public function myRemoteMethod(param1:String, param2:int) : AsyncToken
    {
        loadWSDLIfNecessary();
        var operation:AbstractOperation = _serviceControl.getOperation("myRemoteMethod");
        var token:AsyncToken = operation.send(param1, param2);
        return token;
    }
}

If you've used Cairngorm before, this code should look very familiar.  It's the same type of code that you would normally see in the Delegate layer.

How do we use this type of delegate class in Mate?  My first approach was to try and use a WebServiceInvoker, but the delegate class is not a WebService.  My second approach was to try and leverage AsyncMethodInvoker, but that had a few other problems.  The biggest was that the success/failure listeners respond to the class itself and not the token returned by the method.  Additionally, the AsyncMethodInvoker doesn't integrate with the UnhandledFaultEvent approach to application-wide service fault handling.

So, I decided the best approach was to create a new kind of invoker, DelegateInvoker, specifically to handle calling these types of delegate classes. Usage is essentially the same as the other Mate service invokers:

<DelegateInvoker instance="{ services.myService }" method="myRemoteMethod"
	arguments="{ [ 'param1', 12 ] }"
	showBusyCursor="true">
			
	<resultHandlers>
		...
	</resultHandlers>
			
	<faultHandlers>
		...
	</faultHandlers>
</DelegateInvoker>

If no faultHandlers are defined, then an UnhandledFaultEvent is generated. This allows the DelegateInvoker to integrate with the application-wide service fault handler.

The DelegateInvoker can be used with any method that returns an AsyncToken. Behind the scenes, the DelegateInvoker attaches a responder to the AsyncToken returned by the method. The responder listens for success/failure and triggers the inner handlers when the method call returns. If the method does not return an AsyncToken to attach a responder to a runtime error is logged.

I've spoken with Nahuel about getting this new DelegateInvoker class incorporated into the Mate core. He will be adding it into the Mate in_development branch. It should be available for download in the next day or so, and I'll update this entry when the class is posted.

The DelegateInvoker class is available as of revision 93 in Mate's SVN. It's currently in the in_development branch, but will eventually be moved to the trunk in a future release.

Flex 2.0.1 SDK is dying

| No Comments | No TrackBacks
If you have a project that still uses the Flex 2.0.1 hotfix 3 SDK, now is a good time to consider upgrading.  When the new version of FlexBuilder is released (presumably in the second half of 2009), you will no longer be able to build your Flex 2.0.1 projects using FlexBuilder.

When you try to build a project with the Flex 2.0.1 SDK using the FlexBuilder Gumbo MAX Preview build, you'll encounter an error indicating that the flex-compiler-oem.jar is missing from the classpath.  I've logged this as the following issue: https://bugs.adobe.com/jira/browse/FB-15688.  The issue was resolved as Not a Bug with the comment Flex Builder 4 will not support Flex SDK 2.

I'll repeat that.  On a separate line.  In Bold.  Pay attention.

FlexBuilder 4 will not support Flex SDK 2.

Of course, ANT scripts and command-line compiles will continue to work.  However, losing IDE support should be a pretty compelling reason to look into the upgrade process.

Flex 3.0 was released February 25, 2008.  Since release the SDK has been updated to Flex 3.1 on August 15 and Flex 3.2 on October 29.

To learn more about the Flex SDK and download new versions, visit http://opensource.adobe.com/wiki/display/flexsdk/Flex+SDK.

For those of you looking to upgrade from Flex 2 to Flex 3, check out the compatibility issues in the Flex 3 release notes.

And now, I leave you with Monty Python's "Bring Out Your Dead".  Flex 2.0.1, you'll be stone dead in a moment.

ActionScript 3 Singleton Redux

| 14 Comments | No TrackBacks

Not to beat a dead horse, but....

Ever since developers have been using ActionScript 3 the quest for the perfect Singleton has been underway. The heart of the issue is that there are no private constructors in ActionScript 3. Thus, it's been a tricky road trying to find the best way to prevent other developers from inadvertently invoking a Singleton's constructor and creating an additional (and erroneous) instance.

For example, a quick google search yields quite a few results. Here are a handful of them that I've tried to place in chronological order:

What do I think? My initial reaction was to not worry about it. Seriously, what does it matter? Do we really need compile time checking? Isn't runtime checking and unit testing enough? If a developer uses the class wrong, is that the class author's fault? As long as there is documentation as to what the class is and how it's used, then this is really a non-issue at best and trivial at worst.

Admittedly that's a bit of a naive attitude. However, in over a year of not caring about the private constructor issue I can honestly say that I've never run into a problem with singletons, or had any of my team members accidentally use them the wrong way.

It was actually a combination of other factors (and personal preference) that made me revisit the singleton pattern. The singleton technique that I prefer was developed to address the other issues I was running into and to reflect my personal coding style. While I was at it, I figured I might as well address the private constructor issue too. After all, we all love being smacked around by the compiler sometimes.

The technique I prefer has the following highlights:

  • Usage of static instance read-only property instead of a static getInstance() function. This is somewhat a matter of style and personal preference, but I prefer the succinctness of the read-only property. This is especially obvious when the singleton is used in binding expressions. Plus, getInstance() is so 1990s Java which ActionScript is most definitely not. I kid, I kid. But seriously, ".instance" is cooler.
  • Usage of a private lock class to prevent outside construction. While this is a common theme in the above links, my approach is slightly different. Instead of passing an instance of the private locking class to the constructor, I just pass the Class reference itself. This does two things. First, it clarifies the conditional check in the constructor. The test for the proper locking Class reference communicates the code's intent better than the traditional check for not null. Second, it encapsulates the private locking class itself. The constructor's argument is simply lock:Class which doesn't expose the name of the private locking class to the outside world, but still communicates that the constructor is locked.
  • Removal of 'Unable to bind' warnings in Flex 2. When you use a singleton in a binding expression, it's typical to have the Console log flooded with warning messages indicating that binding to the instance property will not be able to detect updates. My singleton version fixes these warnings.
  • Use of const instead of var for the instance storage. This one is pretty obvious, but using const here communicates intent better. The variable storing the singleton instance is not allowed to change so const is the better choice.

So, with that said, I thought it was worth throwing my singleton version into the ring. This is the method I prefer. If you like it, great. If not, that's fine too. No hard feelings. Really.

Sample code is after the jump.

Do you use the public Flex bug base?

| 1 Comment | No TrackBacks

If you're not familiar with the Flex Bug and Issue Management System, you need to do yourself a favor and get involved.

As I've spoken about before, when the Open Source Flex initiative was first announced one of the things I was most excited about was the opening of a publicly accessible issue management system. I've touched on a little bit of my reasoning here, but wanted to call attention to how awesome a system like this truly is.

If you use Flex day in and day out like I do, chances are you're going to run into issues or things that you think can be improved. That's just the nature of software development. Having access to the public bugbase allows you to be actively involved in identifying issues and helping to improve the product for other developers. Better yet, when you encounter a problem it allows you to defer the work of fixing or working around the issue to Adobe.

Let me share an example to demonstrate what I mean.

Earlier this summer I ran into a strange issue with the DateChooser component. Code that should have worked was failing for no apparent reason.

I opened up a web browser to the Flex bugbase, http://bugs.adobe.com/flex/, and searched for the issue. There are a lot of search options here, but I just used the "Quick Search" to get started looking, and then narrowed down via the extended options.

After searching for my specific issue, I didn't see anything related to the problem I was having. This meant that Adobe was not aware of a potential issue. So, I created a new issue describing my problem.

The process for creating a new issue is really straightforward. Use the "Create New Issue" link and just describe the problem your encountering. Having sample code to reproduce the problem really helps well. When you're done creating the issue it gets assigned an id.

For my particular issue, it was assigned SDK-12004. Since this issue was affecting my ability to complete some code I was working on, I was really interested to find out what Adobe thought and I wanted to be notified if anything changed on the issue. I clicked the "Watch it" link so that any changes to the issue would be emailed to me.

By watching the issue I was able to see it move through the Adobe QA system. I knew who was looking at it and what their thoughts where. I was emailed anytime someone commented on the issue, and ultimately I knew when it was fixed. In this case, another bug was found that was related to my original report but not quite the same, so SDK-12008 was opened as well. I opted to watch that issue too since it also affected what I was working on at the time.

When I saw that the issue was resolved as fixed, I found the comment with the associated build number of the fix. Here's where things get really interesting. The particular issue was listed as working fine in build 179224. Sweet, but where's the code for that?

Did you know there are nightly builds of the Flex SDK?

Did you know that when an issue in the bug system is fixed, you can grab the code for the fix from the nightly SDK having a build number greater than or equal to the issue's "fixed in build" number? You have to agree to the terms of the early build access license, but once you click the checkbox for that there is a matrix at the bottom of the page that populates with links to download the nightly build. Even better, there's a change log for each version.

I scanned the change logs looking for the change set that related to my SDK-12004 and SDK-12008 issues. When I found it, I made note of the files that were changed. Then, I downloaded that particular nightly build that contained the fix.

I should note here that the nightly builds are actually for the upcoming Flex 3 SDK, but my current project is still using the Flex 2.0.1 hotfix 3 SDK.

I used the "underriding" technique that Doug described here to apply the changes to my current SDK. Essentially, I took the code for the files that have changed and created versions of them in my local project. My project now has an "mx.controls.DateChooser" class defined that contains the code from the nightly build. Because it has the same fully qualified name as the default DateChooser in my Flex 2.0.1 hf 3 SDK, the version in my project takes greater precedence and it is what gets compiled into the ptoject and used.

This allowed me to apply only the the relevant changes from the nightly build without affecting the rest of my installed SDK. It took a little bit of effort to remove some of the "Flex 3" features from the updated code to downgrade it to work with the Flex 2.0.1 hf 3 SDK, but it wasn't a difficult process.

If you're already using Flex 3, it's even easier to apply a nightly build. In fact, you can just add the nightly build as a new installed SDK in FlexBuilder 3 and simply recompile your project with that SDK to incorporate the changes. It was only because I'm using an older SDK that I had to go through the process of manually applying the changes.

To summarize:

1. I ran into a bug
2. I looked to see if it was a known issue or already fixed
3. It wasn't, so I told Adobe about it
4. I watched the bug to keep informed of its progress
5. Adobe developed a fix for me
6. I downloaded the nightly SDK that included the code for the fix
7. I applied the fix in my project
8. All is well

A positive side effect here is that the fix now goes out to all developers who will be using the Flex 3 SDK going forward. By identifying issues and being involved you not only help yourself by getting Adobe to do the work for you, but you also help the entire Flex community by allowing Adobe to continually improve an already amazing product.

This process isn't limited to just bugs. If you think something could be done better, log an issue for it. It will get prioritized, and Adobe might even take your advice and build the enhancement into a future version.

So, if you haven't been using the Flex bug base, isn't it about time you start?

Flex 2.0.1 Hotfix 3 - The WebService Fix

| No Comments | No TrackBacks

...and it couldn't have come at a better time for me.

I've been hard at work on a large Flex 2 application that utilizes Web Services to communicate with the back-end. I've run into a number of issues that had to be worked around, all of which appear to be fixed by Flex 2.0.1 Hotfix 3.

It looks like Hotfix 3's main focus has been the Web Service classes, adding more stability and fixing lingering issues. This should be a welcome update to anyone who's been banging their head against a wall using Web Services.

One of the issues in particular, using a secure wsdl switches useProxy to true which breaks applications, was quite a pain to deal with. This is where the Open Source Flex announcement really pays dividends. I was able to find the issue in the public facing bugbase and monitor progress. I was happy to see that the issue was already reported, that it already had a valid workaround, and that it was going to be fixed in an upcoming Hotfix 3 release. Kudos to Adobe for having transparency here.

As with any Hotfix release, if you're not experiencing any of the issues that were fixed then it is not recommend that you upgrade. As they say... if it ain't broke...

However, if you're using Web Services you might want to consider the Hotfix 3 upgrade at http://www.adobe.com/go/kb402381.

I've had a few people ping me recently about unexpected parse errors they've encountered while decoding JSON strings using the ActionScript 3 JSON library (part of as3corelib). The fix is easy, but not entirely obvious.

It turns out that in all of the cases where erroneous parse errors were reported, the JSON string looked something like this:

{ prop1: 12, prop2: "hello, world" }

Can you spot the problem?

According to the JSON spec, the above snippet is not actually valid JSON. The reason? It's because the object property identifiers are not string literals. It may be valid JavaScript/ActionScript for creating an object via a literal, but JSON objects contain pairs of string : value and strings are always enclosed in double quotes.

The ActionScript 3 JSON parser I made is a bit on the strict side, I guess. From what I can gather, a lot of JSON decoders will accept the above snippet as valid JSON. Even worse, a lot of JSON encoders will produce JSON in the above format. That is, when you create a JSON string, behind the scenes the JSON string might not actually be valid. Typically the libraries that produce snippets without quotes around object identifiers will also accept those as valid input, so it's usually not a problem.

So, if you're running into parse errors when trying to decode JSON strings in ActionScript 3... make sure the JSON string is actually valid. The first place to look is for quoted identifiers in objects.

If you're using Ruby on Rails and running into this problem, a simple configuration change on the server end will fix the problem:

>> ActiveSupport::JSON::unquote_hash_key_identifiers=false
=> false

Thanks to Richard Wallace for pointing out the Rails configuration change necessary to produce valid JSON for the ActionScript 3 JSON decoder.



About this Archive

This page is an archive of recent entries in the Flex category.

Flash is the previous category.

General is the next category.

Find recent content on the main index or look in the archives to find all content.

Archives

OpenID accepted here Learn more about OpenID
Powered by Movable Type 5.02