Archive for the 'News' Category

24
Apr

Apple has always been a closed ecosystem - so why are we surprised?

In 1984 Apple spent $900,000 on a commercial during the Super Bowl, and Apple introduced the Apple Macintosh for the first time. It is regarded as a masterpiece in advertising and one of the most successful commercials of all time.

In his 1983 Apple keynote address, Steve Jobs made the following comment before playing the commercial for the first time:

“It is now 1984. It appears IBM wants it all. Apple is perceived to be the only hope to offer IBM a run for its money. Dealers, initially welcoming IBM with open arms, now fear an IBM-dominated and -controlled future. They are increasingly turning back to Apple as the only force that can ensure their future freedom. IBM wants it all and is aiming its guns on its last obstacle to industry control: Apple. Will Big Blue dominate the entire computer industry?”.

screen-shot-2010-04-24-at-73338-am

Ironically, three decades later Steve Jobs is still chasing the Big Blue box, in the past Big Blue was IBM’s nickname and today it’s the blue lego plugin for Adobe.

176

What Steve Jobs was talking about in the 1984 ad was the first IBM PC, which was created using off the shelf parts for the first time and marketed by outside distributors. It was introduced in 1980, and soon after the IBM clones began to pop out everywhere. Due to the use of the same operation system (dos) and low price, the eco-system allowed developers to deploy the same software on different machines. Jobs and his executives decided not to license Apple’s technology or OS to any other company. Back then Apple wanted total control. It wanted to sell all the products that are related to their computers; they wanted no competitors.

So what was the Super Bowl ad all about? That was just a marketing masterpiece, but in reality Apple was always a closed ecosystem. iTune lock your music. WebKit Open source open standards, but allow them to take control. Mac OS was never licensed. iHTML, iPad, and the removal of applications are no different. I would go as far as to say that Apple would want to restrict the entire web if they could, and today with OS X accountimg for nearly 11% of web usage that can be a reality!

Apple always protected their margins by keeping prices too high and controlling the end user. The control was from hardware to software. We all know how expensive it is to purchase any piece of hardware for the Mac in comparison to a PC. The majority of Apple users benefit from the ease of using a closed ecosystem. Since Apple controls the entire cycle from software to hardware, the experience is superior, and the average Joe Schmoe doesn’t really care about Flash, Unity3D, or even if Apple will block Photoshop from OS X 10.7.

Why are so many people surprised then when Apple announced that they are blocking other languages (3.3.1) on the iPhone platform or about yesterday’s news (which we don’t know if they are rumors or facts) that no software will run on Mac OS X 10.7 without being approved and signed by Apple? (according to Rixstep)

I have seen many write in their blogs and post tweets saying that “Steve Jobs has Just Gone Mad” and that “can’t be true” with the context of OS X 10.7 possibly locking the ability to publish apps without Apple’s approval.

The reason many are surprised is that Apple always appealed to the young generation, and we think of Apple as an “open minded” young company. Most designers are using a Mac. Apple store in Midtown and Soho are sexy, and they managed to fool us all with the coolness factor. In reality these are just marketing techniques, and the reality is that Apple’s executive don’t have an open minded mentality - they never had one!

img_1278

Apple has moved from having less than 4% on Apple Computer to close to 10% of USA Market Share today putting it in 4th place behind HP, Dell, and Acer (according to osxdaily). The iPhone is capturing 72% of the smartphone market in Japan (according to BusinessWeek). Additionally, the iPod has half the digital music player market, and iTunes sells 70% of all legitimate music downloads (according to USAToday). Today Apple is capable of putting more restrictions and “crossing lines” since they have much more than 4% market share, and if they piss off some users it won’t affect them much. It can actually benefit them with Joe Schmoe enjoying a great experience on Apple’s computers and devices. Joe Schmoe may not be able to play all the games and surf all the websites, but overall the Apple experience will be superior to the PC experience.

Adobe Open Screen Project with WORA (Write once, run anywhere) concept is a threat to Apple’s closed ecosystem model. Even AIR on Mac OS is a threat since they don’t have full control over what the user installs which may interfere with their possible plan to force people into using iTunes for installing all their software.

Adobe has handed Apple a large development community on a silver platter that can help create more appealing applications and games for iPhone platform. Additionally, Unity3D has helped the iPhone platform with Unity powered games in the top 100 list and some amazing games such as Battle Bears, Zombieville, or Monster Trucks Nitro.

Steve Jobs sees these platforms as a threat to Apple’s closed ecosystem, and it appears that Apple would rather lose a small market share (which is growing fast anyway) rather than allow someone to tear their walled garden down. Some market share reports show Mac OS X has reached a market share of 29% (see here).

However, Apple can’t keep the technology to itself. Just as it happened with PCs, I believe that Apple’s continuous attempt to control music, applications, games and others may be the reason Apple will sink. Already, according to reports iPhone dominates but Android is the fastest growing OS.

sinkship

27
Jan

Looking for a strong AS3/Flex Engineer to work for a high profile entertainment company in LA

We are looking for a strong AS3/Flex Engineer to work as a contractor for a high profile entertainment company in LA. The job description is listed below:

* General qualities
o Good communication skill
o Reliable
o Must be passionate about programming
o Must be able to work under directions and independently
* Programming languages
o Actionscript 3.0
o Flex 3.0 MXML
o Javascript
+ AJAX (DOM manipulation, XMLHTTPRequest, CSS, DHTML)
o Jquery javascript framework
o Good understanding of XML, XSL, XUL, Xpath, etc.
* Software
o Eclipse
o Flex Builder
o Flash CS3
o ANT
o Subversion

Drop me an email if you are interested.

30
Dec

FlexUnit Asynchronous tests with PureMVC Framework

There are very little resources online in term of how to use FlexUnit with PureMVC and TDD, furthermore in many cases it makes more sense to create the tests after user stories are implemented.

Let’s take the application we created for Cairngorm and convert it to PureMVC framework. This is a good exercise since it can help define the different between the two frameworks.

Creating tests with existing framework may be challenging at times. In fact, there are cases where it’s makes more sense to create the test after the code is completed rather than following common TDD practices.

TDD recommend to create the test before writing the code, however working in real life application and with exsiting frameworks you may find that sometimes it’s easier to write the code before the test, especially when you use plug-ins or code generator scripts to create your user gesture automatically. I recommend to use your own judgment and see what’s works best for you.

Take a look at the post I published yesterday:
http://elromdesign.com/blog/2008/12/29/tdd-and-asynchronous-tests-with-cairngorm-applications/

View application and download the source code:
CairngormPM and TDD

In this example I am using the same FeedsPanelViewer.mxml container I created for the Cairngorm application. However, I made few small change to the container. I decided to remove the binding properties and let the mediator handle all the changes in the container.


<mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml"
     layout="vertical"
     width="600" height="450"
     styleName="panelView">

     <!-- Feeds List -->
     <mx:List
          id="feedList"
         change="dispatchEvent(new UserSelectedFeedEvent(FeedVO( feedList.selectedItem )));"
          labelField="title"/>

     <!-- Detail information -->
     <mx:VBox width="540" horizontalScrollPolicy="off" verticalScrollPolicy="off">
          <mx:Spacer height="15" />
          <mx:HBox>
               <mx:Label text="FEED DETAIL:" fontWeight="bold"/>
          </mx:HBox>
          <mx:HBox>
               <mx:Label text="author:" fontWeight="bold"/>
               <mx:Label id="author" width="100%"/>
          </mx:HBox>
     </mx:VBox>

</mx:Panel>

PureMVC Mediator:


package com.elad.TDDPureMVC.view
{
     import com.elad.TDDPureMVC.events.UserSelectedFeedEvent;
     import com.elad.TDDPureMVC.model.FeedsPanelViewerProxy;
     import com.elad.TDDPureMVC.model.vo.FeedVO;
     import com.elad.TDDPureMVC.view.components.FeedsPanelViewer;

     import org.puremvc.as3.interfaces.IMediator;
     import org.puremvc.as3.interfaces.INotification;
     import org.puremvc.as3.patterns.mediator.Mediator;

     public class FeedsPanelViewerMediator extends Mediator implements IMediator
     {
          public static const NAME:String = 'FeedsPanelViewerMediator';

          private var feedsPanelViewerProxy:FeedsPanelViewerProxy;

          public function FeedsPanelViewerMediator(viewComponent:Object=null)
          {
               super(NAME, viewComponent);
               feedsPanelViewer.addEventListener(UserSelectedFeedEvent.USERSELECTEDFEED_EVENT, changeSelectedFeed);
          }

          private function changeSelectedFeed(event:UserSelectedFeedEvent):void
          {
               setDetail(event.selectedFeed);
          }

          public function get feedsPanelViewer():FeedsPanelViewer
          {
               return viewComponent as FeedsPanelViewer;
          }

          override public function listNotificationInterests():Array
          {
               return [
                    FeedsPanelViewerProxy.READ_ADOBE_FEEDS_SUCCESS,
                       ];
          }

          private function setDetail(feed:FeedVO):void
          {
               feedsPanelViewer.author.text = feed.author;
               feedsPanelViewer.category.text = feed.category;
               feedsPanelViewer.description.text = feed.description;
               feedsPanelViewer.link.text = feed.link;
               feedsPanelViewer.pubdate.text = feed.pubdate;
          }     

          override public function handleNotification(notification:INotification):void
          {
               feedsPanelViewerProxy = facade.retrieveProxy(FeedsPanelViewerProxy.NAME) as FeedsPanelViewerProxy;

               switch ( notification.getName() )
               {
                    case FeedsPanelViewerProxy.READ_ADOBE_FEEDS_SUCCESS:
                         feedsPanelViewer.feedList.dataProvider = feedsPanelViewerProxy.feedsCollectionVO.collection;
                         setDetail(feedsPanelViewerProxy.selectedFeed);
                         feedsPanelViewer.title = feedsPanelViewerProxy.panelTitle;

                    break;
               }
          }
     }
}

Proxy:


package com.elad.TDDPureMVC.model
{
     import com.elad.TDDPureMVC.model.vo.FeedVO;
     import com.elad.TDDPureMVC.model.vo.FeedsCollectionVO;

     import mx.rpc.events.FaultEvent;
     import mx.rpc.events.ResultEvent;
     import mx.rpc.http.HTTPService;

     import org.puremvc.as3.interfaces.IProxy;
     import org.puremvc.as3.patterns.proxy.Proxy;

     public class FeedsPanelViewerProxy extends Proxy implements IProxy
     {

          public static const NAME:String = "FeedsPanelViewerProxy";
          public static const READ_ADOBE_FEEDS_SUCCESS:String = 'readAdobeFeedsSuccess';
          public static const READ_ADOBE_FEEDS_FAILED:String = 'readAdobeFeedsFailed';
          public var service:HTTPService;

          public function FeedsPanelViewerProxy()
          {
               super(NAME, new FeedsCollectionVO() );

               service = new HTTPService();
            service.url = "http://rss.adobe.com/en/resources_flex.rss";
            service.resultFormat = "e4x";
               service.addEventListener( FaultEvent.FAULT, onFault );
               service.addEventListener( ResultEvent.RESULT, onResult );
          }

          public function getAdobeFeeds():void
          {
               service.send();
          }

          // Cast data object with implicit getter
          public function get feedsCollectionVO():FeedsCollectionVO
          {
               return data.feedsCollectionVO as FeedsCollectionVO;
          }

          public function get selectedFeed():FeedVO
          {
               return (data.feedsCollectionVO as FeedsCollectionVO).collection.getItemAt(0) as FeedVO;
          }

          public function get panelTitle():String
          {
               return data.panelTitle as String;
          }                    

          private function onResult( result:ResultEvent ) : void
          {
               var feed:FeedVO;
               var item:Object;
               var len:int = result.result[0].channel.item.length();
               var collection:FeedsCollectionVO = new FeedsCollectionVO;
               var dataObject:Object = new Object();

               for (var i:int=0; i<len; i++)
               {
                    feed = new FeedVO();
                    item = result.result[0].channel.item[i];

                    feed.author = item.author;
                    feed.category = item.category;
                    feed.description = item.description;
                    feed.link = item.link;
                    feed.pubdate = item.pubdate;
                    feed.title = item.title;

                    collection.addItem(feed);
               }

               dataObject.feedsCollectionVO = collection;
               dataObject.panelTitle = String(result.result.*[0].*[0]);

               setData(dataObject);
               sendNotification(READ_ADOBE_FEEDS_SUCCESS);
          }

          private function onFault( event:FaultEvent) : void
          {
               sendNotification( READ_ADOBE_FEEDS_FAILED, event.fault.faultString );
          }

     }
}

To test the PureMVC framework I will be using puremvc-flexunit-testing. Our test calls the registerObserver method used for listening for a PureMVC notification on a proxy. We pass the PureMVC view, proxy and information for the AddSync such as the method to send a success response and timeout.


package flexUnitTests.proxies
{
     import com.andculture.puremvcflexunittesting.PureMVCNotificationEvent;
     import com.andculture.puremvcflexunittesting.PureMVCTestCase;
     import com.elad.TDDPureMVC.model.FeedsPanelViewerProxy;

     import flexunit.framework.Assert;

     import org.puremvc.as3.core.View;
     import org.puremvc.as3.interfaces.IView;

     public class ReadAdobeFeedsTestCase extends PureMVCTestCase
     {
          override public function setUp():void
          {
               var facade:ApplicationFacade = ApplicationFacade.getInstance();
               facade.registerProxy( new FeedsPanelViewerProxy() );
          }

          private function get proxy():FeedsPanelViewerProxy
          {
               var retVal:FeedsPanelViewerProxy = ApplicationFacade.getInstance().retrieveProxy(FeedsPanelViewerProxy.NAME) as FeedsPanelViewerProxy;
               return retVal;
          }

          private function get view():IView
          {
               return View.getInstance();
          }

          public function ReadAdobeFeedsTestCase(methodName:String=null)
          {
               super(methodName);
          }

          public function testReadAdobeFeedsEvent():void
          {
               registerObserver(this.view, this.proxy, FeedsPanelViewerProxy.READ_ADOBE_FEEDS_SUCCESS, handleResponse, 300);
               this.proxy.getAdobeFeeds();
          }

          private function handleResponse(e:PureMVCNotificationEvent):void
          {
               Assert.assertEquals("Feed title is incorrect", proxy.panelTitle, "Flex News");
          }
     }
}
22
Oct

New AdvancED Flex 3 book avaliable on Amazon and cover advanced Flex topics

Yesterday APress released the book I co-authored called AdvancED Flex 3. It covers advanced Flex topics such as Ajax, RIA, Web 2.0, Mashups and tons of practical recipes. Jordana, my wife, took an extended break from being an attorney and is doing an amazing job raising our daughter Romi. Without her support, I would not have been able to complete this book. It was pleasure working with Shashank Tiwari, Jack Herrington and Joshua Mostafa.


FACILITATING AUDIO AND VIDEO STREAMING


I showed hands-on techniques for creating a Flex HD video application using Cairngorm. I covered the subject of data layer by designing, configuring, and creating a Microsoft SQL and MySQL database. Creating ColdFusion server side services using best practices to generate services as well as creating custom components to fit the exact needs of the project.

TURBO-CHARGING DATA BINDING


I covered the subjects of explicit and implicit data binding, synchronizing the client model with the server model and binary data objects. I illustrated how to utilize existing plug-ins to create a powerful CRUD applications that can handle processing data and presentation as well as provide fast transmission to the server

FLEX MASHUPS


I showed how to work with Mashup frameworks, dealing with namespaces, interconnectivity and best practices. I covered how to utilize the Web and the enormous amount of resources available, such as: APIs, libraries, custom components, and skins. I showed how to build exciting mashups using some of the most popular APIs such as Yahoo!, Amazon, Flickr, and UMap. I gave tips and tricks on how to start building your own mashup application.

Click here to buy from Amazon!

18
Feb

New advanced flex 3.0 book - Developing Enterprise Architect Applications

I am currently in the process of writing as a co-author in a new book by Apress called: “AdvancED Flex 3″

This book makes advanced Flex 3 concepts and techniques easy. Ajax, RIA, Web 2.0, mashups, mobile, the most sophisticated Web tools and the coolest interactive Web applications are all covered with practical, visually-oriented recipes.

* Practical, how-to approach for advanced results.
* Leverage the tools you know, Java, PHP, Python, Ruby, in combination with Flex.
* Build high-performance Web applications with interactivity that really engages your users

To read more about the book click here.

Additionally, I am in the process of writing the following book:

Advanced Flex 3.0 - Developing Enterprise Architect Applications.
The book will be published in late 2008. The book will cover the subject of developing an Enterprise Level Flex Applications from planning to designing and finally testing. It is intended for the experienced Flex developer wishing to expand his/her knowledge and expertise. Developing a large scale Flex application is different than developing a small application and although there is a lot of information, there is not any one resource that covers it all. This book will cover all the best practices and give you the tools you need to develop such a large scale Flex application.

In the next few months I will be giving away some of the API’s that will be part of the book. To learn more about the book and signup for the pre-order list click here.