DIGG IT!
Published
Thursday, November 29, 2007
at
10:25 AM
.
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 WorldIn 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 :)
DIGG IT!
Published
Monday, November 26, 2007
at
8:25 AM
.
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/http://blogs.moneycentral.msn.com/topstocks/archive/2007/11/26/how-a-little-laptop-is-changing-an-industry.aspxhttp://www.businessweek.com/the_thread/techbeat/archives/2007/11/roll_over_beeth.htmlI 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.htmlhttp://www.abcnews.go.com/Technology/story?id=3922038&page=1http://www.tgdaily.com/content/view/35022/118/http://www.nytimes.com/2007/11/28/us/28hoax.html?em&ex=1196398800&en=b1408a7356b77eef&ei=5087%0AState - 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/welcomehttp://www.picnik.com/app#/edithttp://www.picnik.com/app#/create/effectshttp://www.picnik.com/app#/in/flickrsearchhttp://www.picnik.com/app#/out/facebookProgrammatic - 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/divertedhttp://del.icio.us/tag/{tag}
http://del.icio.us/tag/flexhttp://del.icio.us/{del.icio.us ID}
http://del.icio.us/sfegettehttp://{LANGUAGE}.wikipedia.org/wiki/{WikiName}
http://fr.wikipedia.org/wiki/Ted_WilliamsI 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%20FlexAFTER - 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=0AFTER - 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=adbeAFTER - http://finance.google.com/adbe
AFTER - http://finance.google.com/nasdaq/adbe
BEFORE -
http://finance.yahoo.com/q?s=ADBEAFTER - 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/amphttp://adobe.com/go/tryconnecthttp://adobe.com/go/maxTechnology 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 :)
DIGG IT!
Published
Friday, November 23, 2007
at
9:42 AM
.
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.comCheers,
Ted :)
DIGG IT!
Published
Friday, November 16, 2007
at
3:17 PM
.
I updated the Flash Player Counter code against the 3.2B installs on Nov 11, 2007.
Counter SWFCounter SourceCheers,
Ted :)
DIGG IT!
Published
Wednesday, November 14, 2007
at
7:12 PM
.
Worth checking out, the more you watch the more there is. Finally marketing for Flash begins.
flash on.Oh, make sure to turn the HD on!
Cheers,
Ted :)
DIGG IT!
Published
at
9:00 AM
.
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 :)
DIGG IT!
Published
at
8:38 AM
.
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 SOURCEHere is a sample project that contains the plain css style. Feel free to use it to manage your clients expectations.
Cheers,
Ted :)
DIGG IT!
Published
at
7:42 AM
.
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 + 4Cheers,
Ted :)
DIGG IT!
Published
at
5:43 AM
.
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:
<SWFLoader id="contentLoader" url="content.swf"/>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 :)
DIGG IT!
Published
Tuesday, November 13, 2007
at
10:00 AM
.
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 3Card Shuffle API Tester in Flex 3 SourceI 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/' + 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 :)
DIGG IT!
Published
Monday, November 12, 2007
at
1:52 PM
.
Using the flash.net.Loader or mx.controls.SWFLoader classes it is easy to load any SWF file into a Flex application for display. The problems begin when you want to use these assets at runtime and dynamically load SWF files containing custom MovieClips/Variables/Methods/Etc. This is possible but you must do some prep work to avoid 2 problems:
1. Dynamic access to the loaded SWF file!2. A loaded SWF can only create class instances within itself!
Once you address these two issues, you can really take the gloves off with dynamically loaded libraries and SWF content.
1. Dynamic access to the loaded SWF fileThe first problem is easy, to access methods/properties within a loaded SWF you simply need to make the calls dynamic from Flex so that they compile properly. The Flex compiler wants to know in advance that methods in the loaded SWF file are present and will not let you compile otherwise given that the SWFLoader.content returns a DisplayObject by default. The key is forcing the compiler to evaluate member access into the loaded SWF as dynamic vs the strongly typed value of DisplayObject.
Here is an example:
//Create a loader to load a SWF into.
var myLoader:Loader = new Loader();//Load a SWF into the loader
myLoader.load( new URLRequest( 'custom.swf' ) );
//after the SWF has loaded
//Cast the 'content' property as a MovieClip
//call the getInstance method defined in Frame 1 of my CS3 AS3 SWF file
//note the use of casting via MovieClip at the SWF boundary
MovieClip(myLoader.content).getInstance("DA");Here is the same code without type casting, since .content returns a DisplayObject the compiler complains because there is no 'getInstance' method on a DisplayObject:
myLoader.content.getInstance("DA");In this case the Flex compiler will throw the following error:
"1061: Call to a possibly undefined method getInstance through a reference with static type flash.display:DisplayObject"
Once access to the loaded SWF file is dynamic you are free to call any method or property.
2. A loaded SWF can only create class instances within itself!
The second problem is that Flash Player will only allow a SWF to create instances within itself. The instances can be passed anywhere in the player but the constructor must be called within the scope of the loaded SWF file. Using a Factory-like method we can create a method within the loaded SWF to provide instances to the parent Flex/AS3 application. This is very handy because it allows us to make the interface to generating instances simple. I use a method called 'getInstance" and pass a string that correlates to the class name. In the example below, I simply return a new MovieClip instance when this method is called and create different MovieClips depending on what is requested. The parent Flex app can save these as variables and use them as it wants.
The example below loads a SWF file (cards.swf) containing all the card designs in a deck of cards and instances are created and passed to the parent Flex application. Since the SWF was made in CS3, I was able to design the cards look and feel easily and can provide an FLA to any designer to enhance these.
Runtime Playing Cards
Runtime Playing Cards SourceOnce you pass these two hurdles you can seamlessly integrate dynamically loaded SWF graphics and AS3 libraries into any part of your Flex application at runtime. Let the mayhem begin!
Cheers,
Ted :)
DIGG IT!
Published
Saturday, November 10, 2007
at
7:22 AM
.
In a weird twist of search engine fate, onFlex.org has the #1 image on google for searches "1", "2", "3", "4", "5", "6", "7". During the launch of Flex 2.0.1 I was in Edmonton training Grant Skinners team on Flex and decided to count down to the launch on my blog. Well the number images seems to be very popular and lots of folks link to them. It is a bit weird to be #1 for images of numbers.
Google Images "1"

Google Images "2"

Google Images "3"

Google Images "4"

Google Images "5"

Google Images "6"

Google Images "7"

I want to do something about this number phenomena and understand why google's SEO isolated the number images. It would also be kind of fun to monitize the image traffic or at a minimium understand the traffic and domains where the images are used.
Who knows, it will be a fun experiment regardless and I will keep you posted!
Ted :)
DIGG IT!
Published
Friday, November 09, 2007
at
12:25 AM
.
I gave a presentation on Flex Best Practices at FOTB 2007 and MAX 2007 Japan. The presentation is fairly high level as providing Best Practices guidance is so very precarious. I provided a warning before giving this presentation which I will repeat here:
"Every project targeting Flex is different and thus best practices vary depending on the team involved and the project at hand. I have seen all manner of project practices that work for small teams but fail for larger teams and vice versa. This is my take on Flex Best Practices from having looked at many projects over the past 3 years. In many ways my recommendations should not come as a surprise as these are tenets of classical software development."
SLIDES:
PDF,
SWF,
PPTFILES:
FXP3 (ZIP FX3 Project - With Flex Builder 3 Beta 2, simply import this project.)
Cheers,
Ted :)
DIGG IT!
Published
Thursday, November 08, 2007
at
11:27 PM
.
The price change for Flex 2 is NOW ACTIVE at Adobe.com! There was a delay in getting this active on the store at Adobe.com on November 1 and the pricing is now active as follows:
$249 US - PURCHASE Flex Builder 2
$699 US - PURCHASE Flex Builder 2 with ChartingSorry for the delay.
Cheers,
Ted :)