Cast a loaded Flex Application to an Interface

19 Jan
2010

Over at The Question Room (or @thequestionroom) the banditos received a bunch of tweet questions about a problem @gertjansmits was having when loading a Flex application with a SWFLoader and casting it to an interface.

They’ve called on my help to get the answer ;-)

Download the application FXP (Flash Builder 4 project) or
Run the application (Right click and View Source)

My simple interface class, TestInterface, implements 3 functions, a simple getter/setter pair and a function called sayHello.

TestInterface.as

1
2
3
4
5
6
7
8
9
package com.flexdaddy
{
	public interface TestInterface
	{
		function get givenName():String
		function set givenName(str:String):void
		function sayHello():void;
	}
}

You first need to make sure the Application you are loading implements this interface. My root application tag looks like this:

LoadedApp.mxml

1
2
3
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
        implements="com.flexdaddy.TestInterface"
        width="100%" height="100%">

And then in a Script block I make sure to implement all three functions specified above.

LoadedApp.mxml (LoadedApp.swf)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
	implements="com.flexdaddy.TestInterface"
	width="100%" height="100%" >
 
	<mx:Script>
		<![CDATA[
			import mx.controls.Alert;
 
			private var _givenName:String;
 
			public function set givenName( str:String ):void
			{
				_givenName = str;
			}
 
			public function get givenName():String
			{
				return _givenName;
			}
 
			public function sayHello():void
			{
				mx.controls.Alert.show(  "Hello " + givenName );
			}
 
		]]>
	</mx:Script>
 
</mx:Application>

Now when loading the LoadedApp application when using a SWFLoader in the main application we first need to do the following:

  1. Listen for a SWFLoader complete event
  2. Cast the SWFLoader content as a SystemManager
  3. Add an event listener on the loaded content for a FlexEvent.APPLICATION_COMPLETE
  4. When FlexEvent.APPLICATION_COMPLETE we can cast event.currentTarget.application to our Interface

This will make sense in the code below. You’ll also notice that after we cast the loaded Flex application to TestInterface we can directly call on any methods or properties implemented from the Interface. In this case I set the givenName and call the sayHello function.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">
 
	<mx:Script>
	<![CDATA[
 
		import mx.events.FlexEvent;
		import mx.managers.SystemManager;
 
		import com.flexdaddy.TestInterface;
 
		private var myLoadedApp:TestInterface;
 
		protected function swfloaderComplete(event:Event):void
		{
			// the SWF Loader has complete but we need to wait for the
			// Flex application to load
 
			var loadedApp:SystemManager = event.target.content as SystemManager;
			loadedApp.addEventListener( FlexEvent.APPLICATION_COMPLETE, loadedAppComplete );
		}
 
		protected function loadedAppComplete( event:FlexEvent ):void
		{
			// cast the loaded application to the Interface
			myLoadedApp = event.currentTarget.application as TestInterface;
			myLoadedApp.givenName = "Flex Daddy";
			myLoadedApp.sayHello();
		}
 
	]]>
	</mx:Script>
 
	<mx:SWFLoader source="LoadedApp.swf" complete="swfloaderComplete(event)" />
 
</mx:Application>

And that’s it!

Download the application FXP (Flash Builder 4 project) or
Run the application (Right click and View Source)

Related posts:

  1. Sizing apps within the Loader control
  2. Alert! Alert! Listen to the buttons!
  3. Flex 2 sample application – tudu lists
  4. Build your first AIR application with Adobe Flex
  5. Strongly type a CF return using Cairngorm


3 Responses to Cast a loaded Flex Application to an Interface

Avatar

@gertjansmits asked a bunch of Q’s about loading a SWF with SWFLoader and casting it to an Interface | The Question Room

January 19th, 2010 at 3:36 pm

[...] Over at Flex Daddy Andrew Spaulding (@spaulds) has written a post titled “Cast a loaded Flex Application to an Interface”. [...]

Avatar

Gertjan

January 19th, 2010 at 7:02 pm

Hi Andrew!

Thanks for your post and your effort. I really appreciate it!

But, what you are describing here is exact what I came up with. But it threw a SecurityError.

The .swf that I’m loading is located on a different domain than the parent. So I tried some security settings (I really should dive in more, I know) and ended up with:

_swfLoader.trustContent = true;
_swfLoader.loaderContext = new LoaderContext( true, null, null );
(and as it turns out trustContent is ignored when loaderContext is manually set)

This worked fine when I tested my main .swf on my machine (still grabbing the loaded .swf from the www).
But online it threw a SecurityError when I tried to cast _swfLoader.content to my interface (even when I tried casting it to a SystemManager).

Now my _swfLoader just uses:
_swfLoader.loaderContext = new LoaderContext( true, null, SecurityDomain.currentDomain );

Now it throws a SecurityError offline, but online everything works as expected. (which I like!).

I hope it makes some sense… if not, (and if you’re interested) I’ll explain in more detail.

Again, thanks for your help!

Avatar

Andrew Spaulding

January 19th, 2010 at 7:22 pm

Hi Gertjan,

Oh, loading from a different domain will hit security sandbox issues! You should be able to get around it like you have above… but here’s some code in a little more detail.

The code assumes you set your mx:SWFLoader id=”swfLoader”

import flash.system.SecurityDomain;
import flash.system.ApplicationDomain;

var context:LoaderContext = new LoaderContext();
context.securityDomain = SecurityDomain.currentDomain;
context.applicationDomain = new ApplicationDomain();
swfLoader.loaderContext = context;
swfLoader.source = “http://otherdomain.com/RemoteApp.swf”;

Interested to know if the above works for you. Set this up before you set the source for the SWFLoader.

– Andrew

Comment Form

top