Monthly Archives: November 2007

The ABC’s of AMF


The AMF file format is a binary file format representing a serialized ActionScript object. This file type is used in many places within the Flash Player and AIR for data storage and data exchange. In Flash Player 9 and AIR, the flash.utils.ByteArray class is the primary way AMF is handled. Let’s look at some examples:

//create some AMF within a ByteArray

import flash.utils.ByteArray;

//create a bytearray
var bytes:ByteArray = new ByteArray();

//write an object into the bytearray
bytes.writeObject(
      { myString:”Hello World” , myNumber:21 , myBool:true }
   );

When you write an object into a ByteArray it serializes the object into aa array of bytes using the AMF file format. You can then transfer this file over a network or save it to a file system to be deserialized later. Let’s deserialize AMF:

//create an object and deserialize an object from a bytearray
var myObject:Object = bytes.readObject();

//trace a property
trace( myObject.myString ) // Hello World

In this case the myObject variable looks exactly like the object that was originally put into the ByteArray. Once the AMF data is transformed into a real object again, we can use it in ActionScript identically as before.

In Flash Player AMF is used in SharedObject, RemoteObject, LocalConnection, ByteArray, RTMP (all variants) and all RPC remoting operations. The benefits of AMF are actually really misunderstood, so lets take a quick look:

1. File Size – AMF objects are very small and are compressed using zlib.

2. Fast Serialization/Deserialization – AMF is transformed using native C code in the player so it is blazing fast. The AMF format was designed to serialize and deserialize quickly under low memory and slower CPU conditions. As the AMF data is parsed directly to objects, there is no lag for interpretation or parsing of AMF and creation of objects is done on a single pass.

3. Native Types and Custom classes supported
– You can serialize any object in Flash Player with the only exception being displayObjects. You can also map serialized objects back to custom class instances provided the custom class is in the Flash Player when things are deserialized.

I hear many folks talk about remoting with Flash Player but there is a lower level to remoting in using AMF directly. What is cool here is that you are not limited to traditional RPC using HTTP/HTTPS as Flash Player 9 supports binary sockets in the flash.net.Socket class and stream loading of AMF using flash.net.URLStream class. Better still, you can use AMF to store data on the server side without the server needing to know anything about the objects themselves. It is an ideal way to exchange data and persist objects to disk or to the network.

I would encourage you to take a deeper look at AMF. There are some low level benefits to using it that are hard to beat. With all distributed computing systems, serialized object formats are essential and AMF is the native format for Flash Player.

There is some big AMF news coming in December…. :)

Cheers,

Ted :)

URL Matters


I view the URL/URI to be one of the most essential but often overlooked aspect of a website. I wanted to look at the good/bad uses of URLs within web pages and web applications. Let’s take a look at a few:

Readable – I really like it when a URL is readable and easy to understand. When I read a URL I want to be able to guess at what the page will contain. .

CNET: Does a great job organizing content into directories.
http://reviews.cnet.com/
http://reviews.cnet.com/camcorders/
http://reviews.cnet.com/laptops/

News/Blogs: These sites have clean URLs with hints about the content
http://www.techcrunch.com/2007/11/28/google-earth-heading-towards-extinction/
http://machinist.salon.com/feature/2007/11/28/kindle_review/
<a href="http://blogs.moneycentral.msn.com/topstocks/archive/2007/11/26/how-a-little-laptop-is-changing-an-industry.aspx
“>http://blogs.moneycentral.msn.com/topstocks/archive/2007/11/26/how-a-little-laptop-is-changing-an-industry.aspx
<a href="http://www.businessweek.com/the_thread/techbeat/archives/2007/11/roll_over_beeth.html
“>http://www.businessweek.com/the_thread/techbeat/archives/2007/11/roll_over_beeth.html

I would also bet that SEO crawlers leverage keywords within the URL itself. If I were a robot, I would rank the words within the URLs above higher in my search listings than those below.

These URLs leave a bit to be desired.
http://www.news.com/2300-1041_3-6220161.html
http://www.abcnews.go.com/Technology/story?id=3922038&page=1
http://www.tgdaily.com/content/view/35022/118/
<a href="http://www.nytimes.com/2007/11/28/us/28hoax.html?em&ex=1196398800&en=b1408a7356b77eef&ei=5087
“>http://www.nytimes.com/2007/11/28/us/28hoax.html?em&ex=1196398800&en=b1408a7356b77eef&ei=5087

State – I like it when the URL stays in sync with the state of the page/application. I think Picnik.com does a great job of this. The site is an RIA and the URL is in constant sync with the application. It leverages the anchor # symbol yet provides clean URL paths. You can bookmark any part of the site and return to the state of the application/site at any time. Although this looks easy, it is really hard to do well.

http://www.picnik.com/app#/home/welcome
http://www.picnik.com/app#/edit
http://www.picnik.com/app#/create/effects
http://www.picnik.com/app#/in/flickrsearch
http://www.picnik.com/app#/out/facebook

Programmatic – I really like it when the developer takes the time to make the URL programatic. It is very subtle but I often return when I can go directly to things via the URL.

http://www.flickr.com/photos/{FlickrID}
http://www.flickr.com/photos/diverted

http://del.icio.us/tag/{tag}
http://del.icio.us/tag/flex

http://del.icio.us/{del.icio.us ID}
http://del.icio.us/sfegette

http://{LANGUAGE}.wikipedia.org/wiki/{WikiName}
http://fr.wikipedia.org/wiki/Ted_Williams

I really dislike query string variables in a URL. In many ways it provides a poor interface to a website and adds a ton of gunk to what could be a clean programmatic URL.

Here are a few URLs that could be improved:

BEFORE – http://www.google.com/search?q=Adobe%20Flex
AFTER – http://www.google.com/search/Adobe%20Flex

BEFORE – http://www.amazon.com/s/ref=nb_ss_gw/104-0679262-3347908?url=search-alias%3Daps&field-keywords=wii&x=0&y=0
AFTER – http://www.amazon.com/search/wii

//Grip – I look up stocks all the time. Yahoo and Google make the URL easy to change directly.
BEFORE – http://finance.google.com/finance?q=adbe
AFTER – http://finance.google.com/adbe
AFTER – http://finance.google.com/nasdaq/adbe

BEFORE – http://finance.yahoo.com/q?s=ADBE
AFTER – http://finance.yahoo.com/adbe
AFTER – http://finance.yahoo.com/nasdaq/adbe

I am also a fan of organizing APIs using method+arguments syntax. It makes it easy to see what you are calling as a developer and to allow others to integrate against the API by discovery. Here is an example:

http://ifbin.onflex.org/api/3/search/resultByKeyword/Flex/Adobe/AMF

Essentially this would call a method like so: (the 3 is the API version#)
search.resultByKeyword( ‘Flex’ , ‘Adobe’ , ‘AMF’ );

Short – The shorter the URL the better in my book. I am always amazed at how long URLs can get. I view shorter URLs are just plain better. It almost makes sense for every site to have a tinyurl service within them so that each complex URL can be made simple. At Adobe the go URLs have been very popular as they allow a short programmatic URLs to various parts of the Adobe.com site.

http://adobe.com/go/flex/
http://adobe.com/go/flash/
http://adobe.com/go/amp
http://adobe.com/go/tryconnect
http://adobe.com/go/max

Technology Neutral – I prefer when developers hide the technology in use. Long term this provides the ability to switch between technologies on the server-side. The end user doesn’t care what technology you use, so why let anyone know? In this case I think less is more. If the URL is free of technology, I think it elevates the service in my eyes. Hide the technology you use, it will make you look smart and provide you greater range of options long term. Also once you get into search engines, the URLs are there to stay and you will need to support the URLs presented to your servers.

Outside of Apache/mod_rewrite and Tomcat, there are very few options for simplifying the URL’s a server presents. I have standardized on using Apache/mod_rewrite because it works well and is simple to implement. I would encourage you to take a look at mode_rewrite to simplify the URLs within your application. I need to make better use of this on my site and eliminate the php from my URLs site wide.

Cheers,

Ted :)

Want to work with Flex on the Adobe Media Player team?


I rarely post Adobe job descriptions but this is an amazing job for a leading Flex developer. Here is the job posting:

Adobe is seeking a Senior Computer Scientist with strong Flex or Flash application development experience to join the Adobe Media Player team. The position will be responsible for development of the new Adobe Media Player that will feature Flash Video delivered via the new Apollo runtime still under development.

Key Responsibilities include, but are not limited to:

· Code features with great quality, meeting the agreed upon schedule.

· Advise other engineers of Flex/Flash development techniques and issues.

· Work with QE to resolve bugs and issues to meet agreed quality standards

· Write functional specifications.

· Gather and incorporate specification feedback from QE, engineering, marketing, and other departments.

· Develop task lists and schedules based on completed specifications.

· Engage with customers to resolve bugs and issues in pre-release.

· Interact with product management and team leads to refine feature requirements.

· Works closely with teammates to solve problems, transfer knowledge, and develop over all product architecture.

· Committed to the highest levels of quality; demonstrates accuracy and thoroughness.

Requires:

· Bachelor’s degree in Computer Science or equivalent experience

· Experienced in Flash ActionScript application development

· Experienced in Flex application development

· Typically requires a minimum 5 years of application development experience, with technologies such as Java or Flex

· Experienced in J2EE development or similar technology

· Experience with Object Oriented Design.

· Experience creating Web Service APIs.

· Experience developing automatable test suites as part of development.

· Excellent written and verbal communication skills.

Interested candidates should send their resume to chericks@adobe.com

Cheers,

Ted :)

MAX 2007, Done. MAX 2008, Coming Soon!


I started working on MAX 6 months ago and I have to say it was a blast to contribute to the events in Chicago, Barcelona, and Japan. Overall 2007 marked a great change for MAX as we focused on the community and scaled up the MAX conference in size. Worldwide we reached over 7,000 customers at the 3 events. MAX was great this year because of the community participation and the amazing sessions provided by MAX speakers, for this I need to thank everyone who attended and contributed to MAX. It was a real pleasure to join the MAX team as there are some amazing people who worked really hard to make MAX great. I am looking forward to working on MAX 2008 and I am sure it is going to be a great year.

Over the past month since MAX Chicago we have been compiling a ton of feedback about the events. One of the real problem areas for MAX was the unions in Chicago. There are many complaints about the lack of staff and technical issues and most if not all of these fall into the union management of McCormick place. I wish the situation was different but we couldn’t even plug in a power cord without an electrician and union rep. These issues were non-existant in Barcelona and Tokyo and it was very frustrating to me to see work politics derail well laid plans.

Even with these side efects MAX was still the best event that Adobe/Macromedia has ever had with record attendance and community participation. I am very proud of the results and what we accomplished in a very short time. We have some great changes in store for MAX 2008. I look forward to seeing you in San Francisco and other parts of the globe, Amsterdam or Bangalore sound interesting?

Thanks for your attendance!
Thanks for your participation!
Thanks for all the hard work!
MAX 2007 was a blast!

Time for some much needed diving!

Ted :)

Managing UI Development Expectations with Flex


The default skin in Flex is pretty nice and I have regularly seen this cause problems with consulting projects. The issue is that when you mock up a user interface it looks good by default and the client thinks that development progress is much farther along than it really is. While I was consulting I used a default skin to remove the shine from the Flex UI allowing me to better manage client expectations.

Clients want to see a steady progression of development and if you show them shiny polished ui very early in the development process it can lead to confusion. Clients rarely realize how much work it takes to wire up a UI but they can see visual improvements. My recommendation is to use a plain CSS skin for Flex and dial the chrome down to black and white. It allows you to focus on control layout in prototypes vs having the chrome distract your client.

Here is a simple test. Which UI is more complete?


See my point. To the non-developer manager the first UI looks much better and more complete. The key is to show them the plain one, then later in development work on the custom skin and reveal your development progress later. You will get some strange looks from other developers but your client will have a better set of expectations and the plain skin helps you explain the progress of their application.

SAMPLE PLAIN CSS PROJECT

SAMPLE PLAIN CSS PROJECT SOURCE

Here is a sample project that contains the plain css style. Feel free to use it to manage your clients expectations.

Cheers,

Ted :)

OSX Screen Capture: COMMAND + SHIFT + 4 & COMMAND + SHIFT + 3


I take a lot of screen captures for my blog and always use 3rd party software. It seems that Apple snuck a feature into the OS. Press COMMAND + SHIFT + 4 and you will get a selection cursor. Highlight an area of the screen and it will capture an image to the clipboard. In the finder or on the desktop simply press COMMAND + V to paste an PNG. It is the easiest way to get a PNG of a custom area of the screen in OSX.

Full ScreenShot: COMMAND + SHIFT + 3

Custom Area ScreenShot: COMMAND + SHIFT + 4

Cheers,

Ted :)

Creating class instances dynamically from loaded SWF’s


A few days back I posted on a simple factory-like method for returning class instances from a loaded SWF file. At lunch yesterday with Matt Chotin he mentioned another way which I thought was worth posting. It seems that there is a property on Loader or SWFLoader called ‘loaderContext’ and in turn it has a property called ‘applicationDomain’ and this object has two methods worth knowing about ‘hasDefinition’ and ‘getDefiniton’. Interesting! Here is how to use them:

Say I load a SWF9 file into a SWFLoader instance like so:

In content.swf I have a class named ‘Foo’. To create an instance of Foo dynamically I would do this:

if ( contentLoader.loaderContext.applicationDomain.hasDefinition(‘Foo’)){
    var FooClass:Class =     contentLoader.loaderContext.applicationDomain.getDefinition(‘Foo’) as Class;
    var fooInstance:Object = new FooClass();
}

In this case hasDefinition return a boolean to tell if a class is present in the loaded SWF and if it is present we can obtain the Class using ‘getDefinition’. Then by simply using new with the returned class you can create instances.

What I like about this is that you can obtain Class instances from any SWF9 file without additional code within the loaded SWF. The only downside is that there is no metadata within the SWF file listing the classes available. It would be easy to denote the classes in a SWF file with an array at the root of the loaded SWF file. Regardless, this is a great technique to know about. Kudos to Matt for pushing me deeper into the AS3 APIS.

Cheers,

Ted :)

API’s with Delimited ASCII text vs XML or AMF


I have been working on a card game for AIR and just finished the API for the game. The API returns shuffled decks of cards with some parameters in the URL. In looking at the various formats, I chose delimited ASCII text. The question you are asking is why, well sometimes XML and AMF are overkill and honestly delimited ASCII text is fast to parse and easy to use/debug. On the client side in Flash Player, String.spilt is over 10x faster than both XML and XMLDocument in parsing speed and is linear in performance with size of the text being parsed. If you are simply passing an array of strings, you might want to look at using delimited text. It isn’t glamorous but it works and is easily scalable on the server side with caching and compressed if your server supports gzip.

So here are the API details on the Card Shuffle API:

// Default URL
// 1 is the version # of the API
http://onflex.org/api/games/cards/shuffle/1/

// Decks Parameter – Shuffle 3 decks of 52 cards each
http://onflex.org/api/games/cards/shuffle/1/3

// Jokers Parameter – Shuffle 2 decks of 52 and add in 2 jokers per deck
http://onflex.org/api/games/cards/shuffle/1/2/2/

The logic shuffles an array of cards randomly between 5-20 times and each shuffle uses a new random seed value. This makes it easy to build the game logic client side without having to worry about shuffle randomness and allows for multi-user. More on the multi-user behavior in a later post.

In Flex 3 I wrote a simple API Test client that shows the decks visually. The card graphics are loaded from a Flash CS3 SWF9 file dynamically (more on the technique here) so that I can swap the card designs at runtime as a user preference. So here is the example with full source:

Card Shuffle API Tester in Flex 3
Card Shuffle API Tester in Flex 3 Source

I used a simple HTTPService tag like so:

<mx:HTTPService
id=”shuffleService”
resultFormat=”text”
result=”shuffleServiceResult( String( event.result ).split(‘|’) )”
url=”{‘http://onflex.org/api/games/cards/shuffle/1/&#8217; + decks.value + ‘/’ + jokers.value}”
/>

Note that the resultFormat is set to ‘text’ and when the result event is fired I used String.split to parse the result into an Array. I used the “|” as the delimiter. If you look at the raw text results you will see a number in the first array position, this is milliseconds from 1/1/1970 (Epoch) and makes it easy to transform into a Date object via the constructor like so:

// shift a value off the array, turn it into a number and pass it to the Date constructor
shuffleTime = new Date( Number( data.shift() ) );

Basically this simple API allows me to get shuffled decks of cards for my upcoming AIR game. I will be posting more about the making of as things progress.

Cheers,

Ted :)