Thursday, April 02, 2009

Loading a Flex SWF from a Flash SWF

Using either pure ActionScript or the Flash IDE, there is a trick to loading a SWF generated from a Flex Application from within a Flash/AS SWF. When loading a Flash SWF any developer can use the following code:


var loader:Loader = new Loader();
var request:URLRequest = new URLRequest("http://www.anyurl.com/test.swf");

loader.load(request);
addChild(loader);

If the test.swf has public functions (i.e. public function hello(name:String):String) you could call them like so:

loader.content.hello("Phillip");

Or you could cast the content and use it as an object like so:

var testObject:TestObject = TestObject(loader.content);

This works as long as the SWF was generated from the Flash SDK. The Flex SDK wraps the application in a SystemManager. Since the SystemManager handles (pre)loading the application we cannot guarantee that at load time of the SWF that the application has been instantiated. The good news is that the SystemManager's application property does not get assigned until the application is instantiated so we can setup a timer and test the application property until the application is ready.

WARNING: Blog code has been copied, pasted, and modified. It may not work as is but the approach still stands.

private var loader:Loader = new Loader();
private var timer:Timer = new Timer(10);

public function init():void
{

loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaderCompleteHandler);
timer.addEventListener(TimerEvent.TIMER, checkTimerHandler);

loader.load(request)
}

private function onLoaderCompleteHandler(event:Event):void
{
trace("Application - onLoaderCompleteHandler");
timer.start();
}

private function checkTimerHandler(event:TimerEvent):void
{
trace("Application - checkTimerHandler");
var flexSWF:* = loader.content;
if(flexSWF != null && flexSWF.application != null)
{
timer.stop();
flexApplication = flexSWF.application;
}
}

There are a few other things I'd like to try but this works.