Fan 4.0 alpha: Anatomy of a kick@$$ Flex app

The application I have been working on for the last month and a half finally hit the Comcast Interactive Media (CIM) Labs page. You can launch the application from here.This should still be considered alpha since this is one state of the completed application. Once completed, the application will include the Circular view of the fan that is the traditional view of the Fan, with the ability to switch between the views. I thought I would quickly write some notes on the experience of writing the application that will be in front of a LOT of people very soon.

Why Flex ?

We have some of the best Flash developers here at CIM working in a very traditional software development method. All of our code is written in reusable classes with modularity and startup speed as the primary focus. So to use Flex, something new to a lot of the team, instead of Flash was not a decision taken lightly. The biggest objection was always the size of the swf file generated. However, looking at the design we saw that almost every Flex component was used in the final version of the application. Since new components add only a marginal size to the swf once you have accepted the framework, it seemed to be a good case for using Flex. I would also like to dispel a myth at this point: Filesize does not slow down an application as much as network latency does. If your application pings a server multiple times to get startup data, its going to be much slower than one that loads in all the data at once. So we tried to keep startup calls to a minimum. The Fan also serves only the Comcast high speed cable internet subscribers so we were guaranteed the high speed connection. Moreover, its easy to write a component that does most things right but people tend to forget the small nuances. For example, if you write a drop down box, do you check to see that you may be on the edge of the Flash canvas and may need to drop up to render properly? Most people forget the small things that kill the experience.

Flex Skinning:

We had heard a lot of scary stories on how difficult it is to skin Flex. I think the core reasons people dont skin Flex applications is because the default look seems fine when you start the development (maybe adobe did too good a job on the default look 😉 ). I would like to say, skinning Flex isnt that hard, especially using graphic assets from a swf or something. Skinning in code is a lot more involved and needs a deeper knowledge of the framework. We started with simple symbols-in-a-swf method and later moved to code based skinning. I did run into a few issues with some components where designers wanted the tabs to bleed into the browse-area but Flex kept clipping my skin. We’ll revisit that and I’ll update everyone once I have an answer. But besides that skinning flex wasnt that difficult.

CSS and Runtime style changes:

This was another reason Flex won over a simple AS3 implementation. There were designs around differently skinned instanced of the application and even though we did have a home-grown skinning framework, the one that Flex offers was much more mature. I already have a few prototypes for skinned instances and they work pretty well. The only thing we needed to learn was how to switch graphical assets at runtime since thats a little more work but at the end it was easy to implement.

Custom components, renderers and AS3 wrappers:

There are a couple of custom components in this application but without styling, the application is just a custom video-player, a panel containing a list and a canvas with a tilelist and tab-bar. All the list elements have custom renderers that represent the data. There are some interesting features to note here:
1) The numbered playlist renderer has the number value bound to its index in the list using the itemRendererToIndex property
2) The tilelist renderers have a start animation delayed by a multiple of their row index making the startup animation a lot more interesting.
3) The color of the playlist renderer changes based on if the video is playing or not. This is via the dataBinding classes. I actually have a function bound to the setter of the ‘isVideoPlaying’ property. Again, this required some learning on my part.

The video player itself was written in raw AS3 since we will embed videos at other places outside the Flex environment. So we wrote an AS3 wrapper that listens to Flex events and then calls resize, play pause events on the player. The player talks to Flex via the wrapper as well. Buttons/scrubbers , input boxes etc inside the player were custom classes written in AS3 in the spirit of Flex but not within the framework.

Reverse migration to 9,0,16,0:

This was something that came up that had me stumped for a while. The application worked on a bunch of computers and then wouldnt on others. It was only later I realized that I was using events exposed in the 9,0,28,0 release and since I had Flex 2.01, my code complete suggestions would expose those events and I would use them and it would work great. 9,0,28,0 has api extensions to the player not available in 9,0,16,0. I was using the addedToStage event and that was crashing the app on others machines. And since they didnt have the debug versions, I couldnt view the stack traces. Now like any good developer, I have my debug player set to 9,0,16,0. If you are developing a Flex app that doesnt use fullScreen (or even if it does) make sure it is 9,0,16,0 friendly. You can use the flash.system.Capabilities to check the users Flash player version.

So how was the experience?

The new features in AS3 are just amazing to work with and Flex is just the icing on top! The feature I loved most is the new E4X XML parsing. There are elements in the application that do some non trivial XML parsing and it could all be handled so easy using E4X. At one point I wrote a code that ran through XML, created objects and stuffed them in an array to use later (a-la AS2) and then refactored all the code to just store the XML as a variable and run through it as I would an array. AWESOME !

Custom events rock and stack traces are beautiful to see (umm..not really but you know what I mean).

The other cool thing was the decoupling of UI symbols and the ability to instantiate them in code. All assets are referenced through an AssetManager (Singleton) class that holds the references of the images. These can be swapped easily even at runtime.

Custom namespaces gives us an easy way to grant limited access to properties rather than making them public.

Issues?

No onReleaseOutside event. We went around this by listening to release events on the stage. Every DisplayObject has a reference to the stage so that wasnt too crazy, but seems hack-ish.
Flex builder really needs to know the targeted version for the application and surface events only available on that. Would have saved a lot of time on the backward migration to 9,0,16,0

Lack of private constructors kill the Singleton pattern although there are implementations that do the job, but again: hack-ish.

Depth management is tricky since you cannot allocate a number value to the depth. For an AS3 implementation for buttons, I would have loved to have created the icon on depth 500 and do all the sprite swapping under it. Since rollover, rollout sprites arent created until the event, you have to add them to the depth of the icon making it move up.Not too bad but it gets complicated if you are adding/removing children often.

All in all, phase 1 was really fun (and fast). I have 2 tips for anyone looking into Flex for hardcore development.
1) Know the properties and events available. A lot of properties exist in the framework that I had never used before. Case in point: We were HRule objects or some graphical UIComponent to separate a list from the lower content via a blue line. Turns out Lists have the border style where you can create borders around any or all the sides. All we ended up doing is just creating a pixel border at the bottom. Saved us some memory.

2)Understand data binding. While using the [Bindable] meta tag is convenient, it isnt a panacea. It took me a while to figure out how to use the ChangeWatcher and the BindingUtil class to conditionally bind to different objects (since item renderers are reused in the list as you scroll and you may need a very granular level of control). Maybe I can post something on that later unless someone has seen a good resource on that (please leave a link if you have).

Drop me a comment and let me know what you think so far.

As always, we are still looking for talented Flex / Flash developers so drop me a line at arpit_mathur [at] comcast.net if you wanna be part of the team.

update:

Fan 4 on the blogs (not all flattering of course 😉 )

Mike Potter on Riapedia
Ryan Stewart on ZDNet
Ryan Stewart’s blog
Pete Cashmore on Mashable
Riability
Shelly Powers on burningbird
Cable 360 article: ‘ Comcast Expands Web Video In “Convergence Revolution” ‘
The fan is also featured on scalenine.com

Author: Arpit Mathur

Arpit Mathur is a Principal Engineer at Comcast Labs where he is currently working on a variety of topics including Machine Learning, Affective Computing, and Blockchain applications. Arpit has also worked extensively on Android and iOS applications, Virtual Reality apps as well as with web technologies like JavaScript, HTML and Ruby on Rails. He also spent a couple of years in the User Experience team as a Creative Technologist.

28 thoughts on “Fan 4.0 alpha: Anatomy of a kick@$$ Flex app”

  1. Well I just got these errors while trying to open some of the Music Videos…

    ArgumentError: Error #2126: NetConnection object must be connected.
    at flash.net::NetStream/flash.net:NetStream::construct()
    at flash.net::NetStream$iinit()
    at net.comcast.cmediaplayer.players::AbstractPlayer/net.comcast.cmediaplayer.players:AbstractPlayer::createNetStream()
    at net.comcast.cmediaplayer.players::SpeederaHotPlayer/net.comcast.cmediaplayer.players:SpeederaHotPlayer::createNetStream()
    at net.comcast.cmediaplayer.players::SpeederaHotPlayer/playURL()
    at net.comcast.cmediaplayer::CMediaPlayer/playSpeederaHotVideo()
    at net.comcast.cmediaplayer::CMediaPlayer/playVideo()
    at net.comcast.fan4.widgets::CMediaPlayerFX/::playNextLCVideo()
    at net.comcast.fan4.widgets::CMediaPlayerFX/::onLCPlaylistLoaded()
    at flash.events::EventDispatcher/flash.events:EventDispatcher::dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at Lightningcast::Lightningcast/::parseXML()
    at Lightningcast::Lightningcast/::xmlLoaded()
    at flash.events::EventDispatcher/flash.events:EventDispatcher::dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at flash.net::URLLoader/flash.net:URLLoader::onComplete()

    Like

  2. Hey Arpit,
    great looking app ,nice user experience.

    Heres for the onReleaseOutside issue you can use the FlexMouseEvent

    FlexMouseEvent.MOUSE_DOWN_OUTSIDE for

    Also keep getting Security Sanbox errors which I think can be handled but try catch and maybe display an alert box . But all in all congrats on a great Flex app 🙂

    cheers 🙂
    firdosh

    Error #2044: Unhandled securityError:. text=Error #2048: Security sandbox violation: http://preview.comcast.net/fan4/Fan4.swf cannot load data from http://a248.e.akamai.net/7/800/1133/1171379946/oasc02.247realmedia.com/RealMedia/ads/Creatives/Comcast/CBS_WirelessPromoB_FAN_nogeo/pixel_1x1.gif.
    at Lightningcast::PlaylistEntry/sendAudits()
    at Lightningcast::PlaylistEntry/postPctAudit()
    at Lightningcast::Lightningcast/getNextVideo()
    at net.comcast.fan4.widgets::CMediaPlayerFX/::playNextLCVideo()
    at net.comcast.fan4.widgets::CMediaPlayerFX/::onLCPlaylistLoaded()
    at flash.events::EventDispatcher/flash.events:EventDispatcher::dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at Lightningcast::Lightningcast/::parseXML()
    at Lightningcast::Lightningcast/::xmlLoaded()
    at flash.events::EventDispatcher/flash.events:EventDispatcher::dispatchEventFunction()
    at flash.events::EventDispatcher/dispatchEvent()
    at flash.net::URLLoader/flash.net:URLLoader::onComplete()

    Like

  3. I got the same RTE that Firdosh Tangri is talking about. I’m not sure if all “Security” related Errors can be done away using a try-catch mechanism. The best way is to use the right policy files and the crossdomain.xmls

    Like

  4. Yeah the application does hiccup once in a while (hence the alpha status). Thanks for the link Jude. Raghu, we are working on the crossdomain issue as of right now.

    Like

  5. Pingback: proxieslist.net
  6. This technology is horrible in general for the person who prefers using the keyboard, either because it doesn’t push the programmers to pay attention to usability in that area, or because the technology is inferior or incomplete.

    This is the application as of April 15, 2007, using Firefox.

    I enter the URL into the address bar and press Enter. Now I cannot tab into the application. I am forced to go to the mouse to use it. Ding #1.

    Now, I click to the top left of the application (where it says “Comcast Fan Videos”). Looking at the application, where would be the appropriate widget to gain focus next on the tab? The “Full Screen” button, that is what’s closest. I hit tab and goes to the first entry under “Fan Playlist”. Ding #2.

    Well OK, I’m on the first entry. I want to see the next entry. I hit the “Down” arrow key on my keyboard. The second entry is highlighted. Great now to watch it. Press Enter. Nothing happens! Press the Space Key. Nothing happens! So you can focus on it, but you can’t activate it. Ding #3.

    Well I’ll hit the Tab key. The “x” next to the first entry is highlighted. The highlighted area looks pretty wide, but it’s over the “x”, so I would expect it to delete just that entry. I hit the “Enter” button. Nothing happens. OK, let’s try the “Space” button. Everything in the playlist disappears. I guess the highlight was supposed to be over the “Clear All” instead of that first “x”. Ding #4.

    I hit the Tab button again. I don’t know where the heck the focus is next, because nothing has changed. Is it on the advertisement directly below below the “FAN Playlist”? I hit “Enter” and nothing happens, so I guess not. It isn’t on the “Related Video” area either. I press all the arrow keys and finally get to the right arrow key. Something on the bottom highlights. Oh, I must be in those general tabs on the bottom. But there was no indication to the user that this is where the focus is. Ding #5.

    (The “Search” area and button is to the immediate left of the tabs. Why does the focus go to the content tabs first. When I hit the Tab button, then it goes to the “Search” area next. Completely unordered. Ding #6.)

    OK, another “Tab” key hit and we are in the “Sort By Provider” drop-down. (Not that the user sorts anything. The user is actually choosing a provider, not sorting by provider.) This should be a drop-down, but how do you expand the list? Let me try “Ctrl-Space”. Well, when I do that all the text in the collapsed widget goes away. ??? Ding #7.

    Now, what if I want to control the playing of this video, or “Share This Video”, or “Discuss This Video”, or “CBS News” this video. I can’t do this through the keyboard because you cannot access this functionality. Ding #8.

    OK, I’ve been frustrated enough. I’m getting out of this application and into something more user-friendly. Well, on Firefox I can hit “Alt-D” to go back to the address bar and type google.com. Wait, it won’t let me do it! What about “Ctrl-L”? Nope. Help!! I’ve been held captive by a poorly designed application!!!

    This is what I hate about Flash/Flex. The application developers generally do not put any thought on usability. They focus on flashy stuff that appeals to teenagers. All style, no substance. I’ve yet to see a clean application on Flash/Flex that allows for decent keyboard usability and clean layout. Instead I get sensory overload and poor application design. This is the supposed future of web development?

    Oh well, at least the buttons look pretty!

    Like

  7. @Josh

    Thanks for dropping by my blog and commenting on the Comcast Fan application even if they were scathing.

    Yes, keyboard accessibility has not been built in as yet, but I cant believe you think that is the only metric to judge the merit of any application.Would the lack of it make you not want to use it as of now? We are well aware of the requirement but it wasnt a target for the alpha launch.

    I love the fact that you have dinged the application 8 or 9 times on the same issue. I am glad you coudn’t find any others :).

    On the web, where time to market is everything, Flex let us develop the app in about one month with a skeletal staff. Moreover I NEVER want to do drag and drop using javascript and html. This is NOT what they were designed for. I love html and css and javascript to add some basic interactivity but not for an application.

    Either way, I’ll let you know once keyboard accessibility works.

    Like

  8. Getting the Tabs to bleed into the content area shouldn’t be too hard, but it can depend on how you put the component together and I’m not sure how you guys put it together.

    The way I typically do it is use a TabBar with appropriate skinning for the Tabs and slice the continuation of the Tab graphic and make a background graphic to use for the ViewStack underneath. If you’re talking about the Tabs at the bottom of your app you might need a background graphic for behind the “Search” Text Input and have it continue behind the Tabs.

    I have a couple skins that utilize this technique on scalenine.com. I think the WMP11 skin does this. However, you may have tried something like this already and it may not have worked or maybe your creating the Tab skinning programmatically.

    If you want you can shoot me an email and give a little bit more detail as to what problems you’re experiencing. I might be able to help you out.

    Nice job!

    Like

  9. @ the depthmanagement issue

    I ran into the same issue, being used to put content on various depth from 1000 to other crazy depths like 50000 in AVM1. Even though i haven’t been quite comfy with the method, it annoyed me a bit when i couldn’t do it anymore.

    Anyway, my solution was to extend Sprite and create my own multidimensional controls to create and manage different “levels” i need. Then i override the addChild to never go above these levels. So far it works like a charm and seems like a much more proper way then the old depthmanagement. When the class is made it is just as easy to use as the old way.

    Im coding pure AS3 though, im not sure how it applies to Flex UIComponents, might be abit more tricky… or not 😉

    Like

  10. Pingback: Gregory Smith

Leave a comment