Archive for January, 2010

29
Jan

Creating a WebBrowser app using Robotlegs MVCS implementation in less than 2 min!

MVC Frameworks are notorious for requiring developers to spend most of their time working on the framework’s classes instead of the actual code. Since I posted the article about the Ant tasks for RobotLegs I was asked couple of times to show how to use the Ant tasks.

Why Ant tasks? The whole idea of the Ant tasks is to speed up your development and allow people that are not that familiar with RobotLegs to get started quickly on PC or Mac. I decided to create a video showing how I can create an AIR web browser application using RobotLegs with the MVCS implementation and try to do that in less than 2 mins, pretty bold ha?!

The application is going to be a simple web browser, see final screen shot below:

screen-shot-2010-01-29-at-11102-am

See the video tutorial here:

This movie requires Flash Player 9

In case you are having hard time viewing the video use the following URL:
http://www.screencast.com/users/eladnyc/folders/Jing/media/239bd195-4888-4570-bfea-2ddb1362ea6c

Feel free to download the Ant tasks:
http://github.com/EladElrom/robotlegs-utilities-AntGenerator

Download the WebBrowser AIR project from here.

BTW I did end up cheating and do little copy&paste and it took 2:20 seconds… but you get the point :)

27
Jan

Dear Apple, I will be using #FuckTheIpad hashtag till you install #Flash and #AIR

Today Apple announced the release of the iPad. As someone that owns: iMac 29″, Mac AIR, MacBook Pro and the iPhone I couldn’t be more excited to get a hold of the new device. I had some doubts if Apple will install the Flash Player, but honestly I didn’t think that they will dare to release a device that is capable to use the Flash Player with specs that includes 16GB-64GB flash drive ,1GHz processor and 1024-by-768-pixel resolution. It’s one thing not to install Flash Player on the iPhone with claims that it isn’t ready for the device, but another to release a tablet with the Apple A4 without the Flash Player.

apple-ipad-a4-chip-2_270x119

I was extremely disappointed to find out today that the iPad wont support the Flash Plugin nor Adobe AIR. It probably wont support Flash Lite either. I started the #FUCKTheIpad hashtag on twitter as protest with the following entry:

Dear Apple, I will be using #FuckTheIpad hashtag till you install #Flash and #AIR!

screen-shot-2010-01-27-at-64502-pm

The idea is not to be vulgar or rude, that’s not who I am, but to ensure Apple gets the message and understands that the Flash community has had enough with Apple’s refusal to include Flash in their devices. I don’t believe you can get a true web experience without having the Flash Player installed on a device. Additionally, I believe that the iPad is a great device for developers to develop AIR applications, not to mention it would be great to be able to port existing application such as the New York Times Reader.

In an hour the hashtag was used about 50 times. I encourage the Flash community to use the #FuckTheIpad hashtag when talking about the device on twitter, as well as post letters on the FuckTheIpad.com blog so maybe Apple will understand that we (the Flash community) demand they install the Flash Player, otherwise we wont bless or buy their device.

appletabletb120

Microsoft have tried a similar approach of locking other technologies and end up in court with the EU antitrust action as well as losing the support of many in the development community, since then they have learned. Apple please don’t take the same approach!

To show your support please use the #FUCKTheIpad on twitter and visit http://FuckTheIpad.com, we will post some letters soon and skin the blog.

23
Jan

RobotLegs Presentation Model implementation that access entire component events lifecycle

Last night, I was part of the RIARadio recording about RobotLegs. I have been supportive of the framework ever since I was introduced to it by Joel. We had an awesome time talking about Frameworks, OOP and RobotLegs. I raised a question to Shaun Smith and Joel Hooks about the presentation model vs Mediator and I pointed out that I haven’t seen a solution to the problem I presented on RobotLegs forums. See here. Joel challenged me to create my own implementation. I decided to accept the challenge and take a stab at it and see what I can come up with.

Problem

You cannot capture all the lifecycle events of a components ( such as PREINITIALIZE, INIT_PROGRESS, INITIALIZE & CREATION_COMPLETE) when using the mediator in Robotlegs. In addition I haven’t seen any implementation that uses the Presentation Model (PM) so you can do stuff before the component gets created or just drop an Presentation Model implementation you have done outside of the RobotLegs framework.

Under the hood

So why can’t we capture the component life cycle events in the Mediator?

The reason is that RobotLegs uses the contextView which is using the DisplayObjectContainer. The DisplayObjectContainer capture the event once the view is already added to the stage (see in 231 in MediatorMap.as)

The view gets added to the stage and than “onViewAdded” method being called and the mediator gets created. At this point it’s already too late, since most of the events to init the component have already been fired.

Meaning, even if you’ll change the mediatorBase code to the following:


		public function preRegister():void
		{
			if (flexAvailable && (viewComponent is UIComponentClass) && !viewComponent['initialized'])
			{
				IEventDispatcher(viewComponent).addEventListener('preinitialize', onCreationComplete, false, 0, true);
			}
			else
			{
				onRegister();
			}
		}

You cannot guarantee it will fire the pre-initialize event, and in fact when I have done some testing I found out that many times the if statement doesn’t get executed and it uses the onRegister directly.

Solution

So the options were either to modify RobotLegs entirely or try to create a more elegant solution that will use RobotLegs architecture while providing the ability to create presentation model in RobotLegs. Since I couldn’t think of a solution other than creating my own mapping system for the presentation model I started modifying RobotLegs framework, however as I was modifying the framework it hit me that there is a more elegant solution using the existing architecture.

Feel free to view and download (right click to ‘view source’) the full example from here:

screen-shot-2010-01-23-at-110559-am

Implementation

Let’s take a look at the example in detail. My entry point, main MXML application, calls the context:ApplicationContext just like any Robotlegs (MVCS) implementation. I have added component that gets attached to the view called mainView


<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   xmlns:mx="library://ns.adobe.com/flex/halo"
			   xmlns:context="com.elad.application.*"
			   minWidth="1024" minHeight="768"
			   xmlns:view="com.elad.application.view.*">

	<fx:Declarations>
		<context:ApplicationContext contextView="{this}" />
	</fx:Declarations>

	<view:MainView id="mainView" width="100%" height="100%" />

</s:Application>

Using a presentation model will allows me to easy unit test my application better, since I can create test cases just for the logic and if needed test cases for the view. Additionally, I can replace my view easily and create different views for the same logic, which will help big time with Flex 4 new architecture and Flash Catalyst.

So using presentation model such as passive view I can than split my laundry to two piles, view and presenter:

View:
1. State is in the view
2. Transitions
3. View is passive and is not aware of the Presenter

Presenter:
1. Logic is in the Presenter.
2. Presenter observes view events
3. Presenter updates the view data.
4. Presenter ‘knows’ about the components in the view.
5. Presenter holds the data or point to a data class.

In fact, I have used the exact same example I created for Flash&Flex Magazine with very small modifications. Take a look at TweetListPresenter, which holds the responsibilities that I described:


package com.elad.application.view.presenter
{
	import com.elad.application.view.TweetListView;

	import flash.events.TimerEvent;
	import flash.utils.Timer;

	import mx.events.FlexEvent;

	import org.robotlegs.mvcs.Actor;

	import utils.twitter.TwitterHelper;
	import utils.twitter.events.TwitterHelperFailureEvent;
	import utils.twitter.events.TwitterHelperSuccessEvent;
	import utils.twitter.vo.TweetVO;

	public class TweetListPresenter extends Actor
	{
		/**
		 * Corresponding view
		 */
		private var _tweetListView:TweetListView;

		/**
		 * Method to go and retireve tweets every defined number of seconds
		 *
		 * @param seconds
		 *
		 */		

		public function get tweetListView():TweetListView
		{
			return _tweetListView;
		}

		public function set tweetListView(value:TweetListView):void
		{
			_tweetListView = value;
		}		

		/**
		 *  Twitter helper utility class instance
		 */
		public var twitterHelper:TwitterHelper;

		/**
		 *   Holds a timer so we will be able to update list
		 */
		public var timer:Timer;

		//--------------------------------------------------------------------------
		//
		//  Default Constructor
		//
		//--------------------------------------------------------------------------

		// called right after pre-init
		public function TweetListPresenter()
		{
			_tweetListView = new TweetListView();
			_tweetListView.width = 800;
			_tweetListView.height = 400;

			_tweetListView.addEventListener( FlexEvent.PREINITIALIZE, onPreinitialize );
			_tweetListView.addEventListener( FlexEvent.INITIALIZE, onInitialize );
			_tweetListView.addEventListener( FlexEvent.CREATION_COMPLETE, onComplete );

			twitterHelper = new TwitterHelper();
			twitterHelper.addEventListener( TwitterHelperSuccessEvent.RETRIEVE_TWEETS, onRetrieveTweets );
			twitterHelper.addEventListener( TwitterHelperFailureEvent.SERVICE_FAILURE, onFaultRequest );
		}

		public function retrieveTweetsEveryFewSeconds( seconds:int ):void
		{
			timer = new Timer( seconds*1000, 100000 );
			timer.addEventListener( TimerEvent.TIMER, onTimerHandler, false, 0, true );

			timer.start();
		}

		//--------------------------------------------------------------------------
		//
		//  Handlers
		//
		//--------------------------------------------------------------------------		

		private function onPreinitialize(event:FlexEvent):void
		{
			// implememt
			trace("onPreinitialize");
		}

		private function onInitialize(event:FlexEvent):void
		{
			// implememt
			trace("onInitialize");
		}

		private function onComplete(event:FlexEvent):void
		{
			trace("onComplete");
			retrieveTweetsEveryFewSeconds( 2 );
		}

		/**
		 * Method to handle a timer event
		 *
		 * @param event
		 *
		 */
		private function onTimerHandler( event:TimerEvent ):void
		{
			twitterHelper.retrieveTweetsBasedOnHashTag( "FlashAndTheCity" );
		}

		/**
		 * Handler for results
		 *
		 * @param event
		 *
		 */
		private function onRetrieveTweets( event:TwitterHelperSuccessEvent ):void
		{
			var dataProvider:Array = new Array();

			event.collection.forEach( function callback(item:TweetVO, index:int, vector:Vector.<TweetVO>):void {
				dataProvider.push( item );
			} );

			this._tweetListView.dataGrid.dataProvider = dataProvider;
		}

		/**
		 * Handler for fault
		 *
		 * @param event
		 *
		 */
		private function onFaultRequest( event:TwitterHelperFailureEvent ):void
		{
		}
	}
}

Couple of things to notice.

  • Actor - The presenter extends Actor just like any other RobotLegs actor
  • Component’s life cycle events - The default constructor creates the passive view and set the size as well as the component’s life cycle events

The view is passive and just holds the component (in our case a DataGrid):


<s:Group xmlns:fx="http://ns.adobe.com/mxml/2009"
		 xmlns:s="library://ns.adobe.com/flex/spark"
		 xmlns:mx="library://ns.adobe.com/flex/halo"
		 width="400" height="300">

	<mx:DataGrid id="dataGrid" width="500" height="400" />

</s:Group> 

The next step is to create the mediator for the main view:


	public class MainViewMediator extends Mediator
	{
		[Inject]
		public var mainView:MainView;

		[Inject]
		public var tweetListPresenter:TweetListPresenter;			

		override public function onRegister():void
		{
			mainView.addElement( tweetListPresenter.tweetListView );
		}
	}

Notice that I am using the DI to inject the presenter just as we do to any Actor in RobotLegs:
[Inject] public var tweetListPresenter:TweetListPresenter;

And once the main view is registered I can than add the component to the display:
mainView.addElement( tweetListPresenter.tweetListView );

Lastly, I need to map everything up in the ApplicationContext class:


		override public function startup():void
		{
			//todo: add commands
            commandMap.mapEvent(ContextEvent.STARTUP, StartupCommand, ContextEvent, true);

			// todo: Add Model
            injector.mapSingleton( TweetListPresenter );

			// todo: Add Services

			// todo: Add View
            mediatorMap.mapView(MainView, MainViewMediator);

			// Startup complete
			dispatchEvent( new ContextEvent( ContextEvent.STARTUP ) );
		}

Take a look at the folder structure:

screen-shot-2010-01-23-at-113505-am

Feel free to download the full example from here, and let me know your thoughts.

Cheers :)

19
Jan

Flexunit 4 with Test Driven Development article on FFDMag

I recently published an article on Flash&Flex Magazine about Flexunit 4 with Test Driven Development. You can download it from here:
http://ffdmag.com/magazine/991-flash-and-mobile-apps-iphone-and-ipod-touch

I decided to use a real life example to help reader better understand FlexUnit 4 and TDD. While trying to come up with an example, I realized that one of my tasks these days is to create and AIR application similar to Adobe MAX Companion AIR Application for a conference I am organizing called FlashAndTheCity. Creating a real application can show you how the process goes in real development and not in a fake example that tries to make everything simple and easy. Creating applications is complex and changes often even as you build your application.

Feel free to download from here and feel free to ping me with any feedback:
http://ffdmag.com/magazine/991-flash-and-mobile-apps-iphone-and-ipod-touch

19
Jan

I am very pleased and honored to join the Adobe Community Experts, now called Adobe Community Professional

I am very pleased and honored to join the amazing list of Adobe Community Experts, now called Adobe Community Professional, this year. It is very gratifying to be acknowledged for the work one put into the Flash community and I will be continue my commitment to share my knowledge as well as help the Flash community with my own event (FlashAndTheCity) as well as speaking and helping other Flash events.

So what is the Adobe Community Professional (ACP) program anyway? “The Adobe Community Experts Program is a community based program made up of Adobe customers who share their product expertise with the world-wide Adobe community. The Adobe Community Experts’ mission is to provide high caliber peer-to-peer communication educating and improving the product skills of Adobe customers worldwide.” - http://www.adobe.com/communities/experts/

Thanks Adobe!