Thursday, February 5, 2009

Calling functions on applications loaded using SWFLoader

Following on from my last post on passing parameters to an application that is loaded using SWFLoader, this post will show you how to call a function on an application.
Here is the code to load swf:
var loader:SWFLoader = new SWFLoader();
loader.addEventListener(Event.INIT, swfLoaded);
loader.load("AnotherSWF.swf");
And here is the code to handle adding the new swf content application:
private function swfLoaded(event:Event):void {
  var content:DisplayObject = loader.content;
  // Or if you don't have the loader:
  // content = event.target.content;
  // add loaded SWF to a UIComponent to show it on the screen
  uicomponent.addChild(content);
  var sysmgr:SystemManager = (content as SystemManager);
  // must wait for the swf application to finish loading
  // otherwise the application is null
  sysmgr.addEventListener(FlexEvent.APPLICATION_COMPLETE, swfAppComplete)
}
And here is the code to call a function on the swf application:
private function swfAppComplete(event:FlexEvent):void {
  var sysmgr:SystemManager = (event.currentTarget as SystemManager);
  var swfApp:Application = (sysmgr.application as Application);
  // call your function here, maybe add error checking
  if (swfApp.hasOwnProperty("helloWorld")) {
    var helloWorld:Function = (swfApp["helloWorld"as Function);
    helloWorld("hi");
  }
}
Note that the SWFLoader has 2 events that could be used:
  • Event.COMPLETE ("complete") - dispatched when the content loading is done
  • Event.INIT ("init") - dispatched when the properties and functions of the loaded SWF are accessible


  • If you want more reading on this subject, here is another good blog on Nested SWF communication.

    11 comments:

    James said...

    This is what I was looking for. Thanks a lot for sharing.

    Anonymous said...

    an swfloader doesn't have a load-function, or?

    Chris Callendar said...

    I'm not sure I understand your question. From what I can see in the LiveDocs the SWFLoader class definitely has a load function.

    Stace said...

    Any idea how to code an AS3 swf file so that it can load swfs into your Flex swf loader? I've got a Flex e-learning app that loads lesson SWFs into the main SWFLoader, but I'd like to load smaller video swf's via buttons on these pages directly into the other SWFLoader in the flex app. Do I need to add some code to the Flex app as well as the SWFs in order to accomplish that? (they are each 1 page swfs representing lesson pages)

    thanks in advance!

    Chris Callendar said...
    This comment has been removed by the author.
    Chris Callendar said...

    Haha, sorry I don't think I follow!
    So each lesson is a separate SWF right? And your main Flex app loads each lesson SWF. Then you want a button on a lesson page to load another video SWF? Is this right?

    I made a simple example here that shows loading nested SWFs in case that helps:
    SWFLoaderOne

    Stace said...

    ah yes very cool! the 2 loaders are both in the Flex app - I don't want to load within the lesson swf, but rather in the tutor swf which is above the lessons xml tree - I'll download your source to see if that works for it though.

    Stace said...

    here is a super rough looking sample of our a page from our app (we're working on the coding stuff and not layout yet :)

    http://www.instaspanish.com/images/sample.jpg

    Anonymous said...

    I think there's a slight error. The DisplayObject added to the uicomponent is the loader itself (or event.target), not its content.

    Chris Callendar said...

    You're probably right, the loader should be added as a child of the uicomponent instead of the content. But I've found that when I do that loader.width and loader.height properties (as well as loader.contentWidth and loader.contentHeight) are zero. Where as the content.width and content.height properties have the proper size. Sop to fix this I had to manually set the the loader's size like this:
    uicomponent.addChild(loader);
    loader.width = content.width;
    loader.height = content.height;

    And now the loader will be correctly sized. Thanks for the comment.
    Chris

    Adrian Pirvulescu said...

    Hi! Nice work ! :)

    I posted something related to flex-flash communication and function calls between them.

    You can find infos like:
    - How to listen for flash events from flex
    - How to call a flash function from flex

    here: http://blog.timeister.com/2009/06/24/call-function-from-flex-to-flash/