Recent Tweets

Friday, April 23, 2010

Web Design of the Year 2009

O.C. Tanner had its annual Designing in the Trenches year-end competition a little while back. The winner for the Print category for the Design of the Year was Dave Clark for some Amtrak collateral pieces. The competition was tough for the Non-Print/Web category. Some designers had multiple pieces submitted, while I only had one design that was as finalist. When they called the winner they announced the designer with the piece that was designed. When the piece was unveiled, I knew right away they made a mistake. Somehow they announced the right designer but wrong developer. Mike Overton was the designer, who had submitted another piece with Chase Maxfield, another Flash Developer, but that was not the piece that was unveiled. The winning design was for Roche, the one I did the development on with Mike as the Designer.

I was at a loss what I should do. Chase had already made his way to the front and was being handed the trophy. I leaned over to those at my table and said, "That is the one I did!" I then decided to walk up to the front to tell our VP that he had made a mistake. It was a little embarrasing for both of us. I had to take the trophy away from Chase, a trophy that did have my name already engraved on it.

In addition to receiving the trophy and gaining the Web Design of the Year title (for the second year in a row now), I also received a gift of my choosing. I picked a nice Dyson vacuum. It was a nice honor to be given this opportunity to win two years in a row. Is everyone tired of me winning yet?

Thursday, January 7, 2010

Odd TypeErrors When Loading and Parsing XML in AS3

Recently I was running into this issue with three TypeErrors when loading an XML file. The following errors were:

  • TypeError: Error #1088: The markup in the document following the root element must be well-formed.
  • TypeError: Error #1089: Assignment to lists with more than one item is not supported.
  • TypeError: Error #1090: XML parser failure: element is malformed.

The errors that were getting thrown were not consistent and made no sense as the XML file was, in fact, well formed.I did a bit of research and found some interesting things out on the erros. The most common errors were #1088 and #1090, but each time the Flash was published, it hit a little differently. At times it would even parse correctly and may data could be used as desired.

At first I thought it was occuring upon the load of my XML file. I attempted to use xmlLoader.addEventListener(ErrorEvent.ERROR, xmlError); However, the error was never being traced within the Loader Error handler. I then did further tests to see when at which point it was actually happening. It was definitely not an IO_Error that was occuring either, for the XML file was being seen and always loaded. The error turned out to be not on the load of the XML, but after it was fully loaded.

So, on the xmlLoader.addEventListener(Event.COMPLETE, xmlLoaded), I found that something was happening when putting the data into the XML Object:

function xmlLoaded(evt:Event):void {

trace(evt.target.data) // data shows up

programXML = XML(evt.target.data);

// error gets thrown here

}

 

My Solution for Bad Parsing

I thought there was an Asynchronous way to add an event listener to an XML object llike you can with a Loader object to listen for an error, but there is not. It must be done in a synchronous way. In other words you cannot put a listener on an XML Object to listen for an Error Event. It must be done as a synchronous catch event:

function xmlLoaded(evt:Event):void {

try{

programXML = XML(evt.target.data);

setData(programXML);

} catch (error:TypeError){

xmlLoader.load(xmlURL);

//trace("A TypeError has occurred : \r\t" + error);

}

}

Since it made no sense to me why it was so buggy I decided to reload the XML file and try to parse it into the XML Object until there was no errors. Granted, this could end up being an infinite loop if the XML at some point ended up being malformed. Therefore, it would be a good idea to put a timout or counter on the loop to stop trying to reload the XML file and do something else. I'm not sure this is best practice, but it was a way around this crazy error that would sometimes hit and sometimes run just fine.

Conclusion

Strange things happen when trying to parse a simple XML file. It is a good idea to use a catch in your code, especially when the code must be run in a syncrynous order. When you have a bug, the error is not always where you think it is coming from.

Sunday, November 1, 2009

Designing in the Trenches Web Design Winners

Recently we had the quarterly "Designing in the Trenches" competition at O.C. Tanner. The competition was as always tough as we have many great designers at Tanner's. Through a joint effort with Mike Overton as the key designer and myself as the Flash Animator, we pulled off a win in the non-print category of the competition.

The Design

The design was for the global pharmaceutical company F. Hoffmann-La Roche (aka Roche). It includes interactive rollover to engage the user with different typography as they explore the various programs within the navigation. It was a solution that wouldn't have been pulled off as well without the strong typography the rollover effects created.

View Site

All in all, everything came together well as Mike and I collaborated on this project. Thank you all who participated in this quarter's tough competition. Everyone's work was outstanding.

Friday, October 23, 2009

Actionscript 3: reference to stage is null

While writing a custom Class in Actionscript 3 today I came across an issue that took me a little bit to figure out where the compile error was coming from. I was getting the wonderful error:

TypeError: Error #1009: Cannot access a property or method of a null object reference.

After a bit of troubleshooting I discovered that a reference to the stage in my Class was returning null. I did some research and found that the stage is really a DisplayObject's reference to the stage DisplayObject.stage. However, if that DisplayObject is not yet added to the stage, the stage of the DisplayObject is not instantiated yet and returns a null value. In my case, the class was a Sprite I was adding to the stage at runtime.

I then discovered that my Class shouldn't get initialized until it was fully added to the stage since I had calls to the the stage class such as stage listeners and stage properties. I then determined that it was essential to add an event listener for my Sprite to be added to the stage:

...

public function myClass()
{

addEventListener(Event.ADDED_TO_STAGE, init);

}

...

Once the Object is added to the stage, you can initialize the rest of the Class. This was an easy fix to the issue that I hope others find useful.

Monday, August 24, 2009

Flash AS3 Garbage Collection

New developers and/or Flash designers make the mistake of forgetting to clear an object when it is finished being used so that it is available for garbage collection. Many noobs simply don't understand the importance and/or rules behind the Flash Player Garbage Collector. Some think that if you simply remove a child object from the stage, or simply made an object null, all is done and memory is automatically freed up. This is a misnomer and if you continually add large objects at runtime, especially with bitmaps and video, you quickly see a performance hit to the processor. This slowness is evident more quickly on slower computers, like the one I have at work, than on newer/faster computers. Sometimes it is a good thing to test on slower computers to help indicate if your application is overly obtuse due to poor garbage collection.

I have made many of common errors of non-garbage collection myself and have found it imperative to clear any (even weak) reference to an object. I found that it is easiest to do this early on in development while you are adding the reference to think of the way it will be removed. For example, when you add and event listener, know when that event listener is finished and remove that event listener:

var image:Loader = new Loader();

var urlReq:URLRequest = new URLRequest("image.jpg");

image.load(urlReq)

image.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);

function completeHandler(event:Event){

//once image is loaded you can stop listening for it to load

event.target.removeEventListener(Event.COMPLETE, completeHandler);

}

I have found that it is best to set up a class for an image loader as it is something that gets used over and over. One thing for certain to use within your ImageLoader class is an unload listener that will remove all soft references to the object so that it will be available for garbage collection.

...

function unLoadHandler(event:Event) {

// remove any listener you have created if you want it to be disposed of durring GC.

event.target.removeEventListener(Event.UNLOAD, completeHandler);

// you should have set up a error handler listener. Be sure to remove it as well

event.target.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);

}

This way when you say image.unload(), your Loader Object will remove all listeners to that object so that it can be disposed of automatically when the Garbage Collector hits. Personally I think this should be automatic by default and remove any and all references to the object, but it is not and it is up to the programmer to set it up that way.

Once you make a conscious effort to be aware of the way the garbage collector works, you will more readily be able to remove all references to the object. If you add the code to remove the listener while it is on your mind to add the listener, you can keep your application cleaner and leaner for a better end-user experience.

Wednesday, August 19, 2009

Johnson & Johnson Design

Lately I have been doing some Flash development for one of our larger clients at OC Tanner, Johnson & Johnson. It is great to do work for such big clients, but with it comes great responsibility. If I fail to deliver good design with a solid implementation of that design, it affects so many parts of our business. I am up for the challenge as I am used to doing such important work for the big guns. I find I deliver more polished work when under greater pressure.

The current J&J design, one of which I am not yet at liberty to disclose, includes some intense Flash and Actionscript 3 programming. It is getting pretty slick the way it pulls dynamic content through XML to engage the user. It will help the user considerably from the current program. I have been learning so many things with garbage collection, classes, keeping my code clean, and such. It is easy to slip into sloppy practices, but with some discipline I keep things somewhat organized. I know there are many AS3 best practices that I may not be following, but I think I am doing pretty good for being completely self-taught.

I hope to do a blog on some of the things I have learned in AS3 this past little while. Some things include:

  1. Garbage Collection
  2. Parent Scope (i.e. MovieClip(parent))
  3. Class Organization
  4. Event Listeners
  5. Actionscript vs. Javascript

...to name a few.

Labels: , ,

Tuesday, July 28, 2009

eLance Work

I have been attempting to get a little freelance work via eLance. I am not yet convinced that it is worth my time it takes to bid for jobs that I most likely will get outbid by. There are too many people out there worldwide that are willing to work for pennies that I simply cannot beat their low bids. I understand that people want inexpensive work, but at what cost are they agreeing to have work done for them that is shoddy with no guarantee of quality delivery? I cannot work for so little people out there are bidding on. It is why the reported overall revenue generated through eLance is lower than one would think. I think I will stick to bettering my portfolio and going after real prospects for my contract work.

Labels: , ,