Home » ActionScript 3.0, Adobe, Flash AS 3

SWF to SWF Communication in FLASH CSx:
how to call methods between swf files

18 August 2009 5 Comments

Two of the most popular questions when loading SWF files in Flash CSx / AS3 are:

  • how to call a method in the loaded swf from the Main document class
  • how to reference at the main document class to call a method from the the loaded swf.

In this post I’ll provide you a quick and easy sample to cover both situations.
This is not the best way to accomplish this task but it’s very easy to understand and use.

So what we’ll do?

1) We’ll load the file Page.swf inside Main.swf clicking on the LoadSwf Button
2) When loading is completed we’ll enable the Call Method inside SWF button
3) Clicking on this button we’ll call a method inside Page.as Document Class. In few words, we’ll move a MovieClip inside the loaded page from the main.fla
4) From the loaded swf (Page.fla) we’ll call a method inside the Main Document Class clicking on the Orange Rectangle button. This method will remove from displayList the loaded swf

Here a Live Demo (click on Buttons to see how it works):

This movie requires Flash Player 10

CREATE THE .FLA FILES:

We first create a new Flash AS3 File, main.fla, with two Button Components (see image below).
We’ll create in the next paragraph its document Class called Core.as.

mainfla

The second step is create the loaded page, page.fla.
It will contain only a MovieClip (an orange Rectangle), with istance name: btn. See image below

pagefla

Following the full-commented Document Classes:

Core.as (linked to Main.fla)

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package {
	import flash.display.Loader;
	import flash.display.MovieClip;
	import flash.display.DisplayObjectContainer
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.events.IOErrorEvent;
	import flash.net.URLRequest;
 
	public class Core extends MovieClip {
 
		private var loader:Loader;
		private var loaderContent:Object;
 
 
		/**
		* Constructor
		*/
		public function Core () {
 
			callSwfMethodBtn.enabled = false;
 
			// Load SWF button
			loadSwfBtn.addEventListener(MouseEvent.CLICK, loadSwf)
 
			// Call method inside the loaded SWF (this button will be enabled after the SWF loading)
			callSwfMethodBtn.addEventListener(MouseEvent.CLICK, callExternalMethod)
 
 
 
		}
 
 
		/**
		* Load the SWF
		*/
		public function loadSwf(e:MouseEvent=null) {
 
			if (loader == null){
				loader = addChild(new Loader()) as Loader;
				loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
				loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, errorHandler);
				loader.load(new URLRequest("Page.swf"));
			}
 
		}
 
 
 
		/**
		* Unload the SWF
		*/
		public function unloadSwf() {
			trace ("doSomething on Core.as (Main.fla)");
			callSwfMethodBtn.enabled = false;
			loader.unload();
			loader = null;
 
		}
 
 
		/**
		* Invoked when SWF is loaded
		*/
		private function completeHandler (e:Event) {
			trace ("SWF Loaded!");
 
			// Enabled 'call Swf method' button
			callSwfMethodBtn.enabled = true;
 
			// Save SWF content Reference
			loaderContent = e.currentTarget.content;
 
 
		}
 
 
		/**
		* Invoked if there are some loading swf issues
		*/	
		private function errorHandler (e:IOErrorEvent) {
			trace ("Unable to load SWF");
		}
 
 
 
		/**
		* Call methods inside the loaded swf
		*/		
		private function callExternalMethod(e:MouseEvent):void {
 
			// Call moveButton() method inside the loaded swf using the loaderContent reference
			// NOTE: it will move the orange Rectable) 
			loaderContent.moveButton();
		}
 
 
 
 
	}
}

Page.as (linked to Page.fla)

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
37
38
39
40
41
42
43
44
45
package {
 
 
	import flash.display.MovieClip;
	import flash.events.MouseEvent;
    import fl.transitions.Tween;
	import fl.transitions.easing.*;
 
 
	public class Page extends MovieClip {
 
		/**
		* Constructor
		*/
		public function Page () {
 
			// Enable CLICK event on the Orange Rect Button
			btn.buttonMode = true;
			btn.addEventListener(MouseEvent.CLICK, destroyMe) 
 
		}
 
		/**
		* Move the button with a Tween animation
		* NOTE: this method IS CALLED FROM the Main.fla Document Class (Core.as)
		*/
		public function moveButton():void  {
			var myTween:Tween = new Tween(btn, "x", Elastic.easeOut, 0, 200, 1.5, true);
 
		}
 
 
		/**
		* Unload the Swf 
		* NOTE: this method CALLS the 'unloadSwf' method inside the Main.fla document class (Core.as)
		*/
		private function destroyMe(e:MouseEvent):void {   
			// Call a method on the root swf
			(root.loaderInfo.loader.root as Object).unloadSwf();
		}
 
 
 
	}
}

Download Source Code (FL CS4)

5 Comments »

  • amsicora said:

    Ottimo tutorial, incredibilmente chiaro.
    Tuttavia, mi sapresti dire perché nella riga 39 di Page.as hai usato
    (root.loaderInfo.loader.root as Object).unloadSwf();
    piuttosto che:
    (root.loaderInfo.loader.root as MovieClip).unloadSwf();
    dato che Page.as deriva proprio da MovieClip.

    Ciao

  • Fabio Biondi (author) said:

    You are absolutly right!!
    MovieClip was the best choice in this situation (i just used Object to cover all the possible situations, i.e. if you load an swf inside a Sprite)

    However thanx for your comment. It’s the first one :) and sorry if i’m answering you in english but i’m trying to port my blog in this language (even if my English is not so good ; )

    Fabio

  • amsicora said:

    Thank you very much, henceforth I will post only in English.
    Bye

  • Maurycy Zarzycki said:

    Pretty clean solution. I think this is the best thing you can do to make it work quickly and effectively, although I am also considering an event based solution but I guess one can settle at this too :).

  • cod3monk3y said:

    Very nice, clean code. I have a few notes to point out

    1. be sure to use “loader.contentLoaderInfo” and NOT “loader.loaderInfo”

    If you use “loaderInfo”, on line 73 you will find that e.currentTarget.content is actually “Core”. Using “contentLoaderInfo” will give you “Page” as expected.

    2. Use namespaces or a new application domain

    Since both your SWFs have the default package (none), all your code from the loaded SWF will be loaded into the loading SWF. If your main classes have the same name in both, there will be a name collision and your LOADED SWF will use the code from the LOADING SWF.

    This can manifest in several ways, but usually just in massive amounts of confusion. If you try to load a SWF in your addedToStage handler, you’ll find yourself in an infinite recursion.

    The first solution is to use namespaces. This ensures that if you have any classes with the same names that there are no name collisions (and no infinite recursion, and no mysterious behaviors). This solution is acceptable. However, the classes that you load will NOT unload when your unload the loaded SWF. And if you don’t control your LOADED (Page) SWFs, you can’t guarantee the safety of your Core application.

    The second (and better) solution is to use a new application domain for your loaded SWF. This completely isolates the code that you’re loading, ensures there are no name collisions, and saves you a ton of headache. Your code then changes to this:

    loader.load( new URLRequest(”Page.swf”), new LoaderContext(false, new ApplicationDomain()));

    Cheers,
    cm

Leave your response!

Add your comment below, or trackback from your own site. You can also subscribe to these comments via RSS.

Be nice. Keep it clean. Stay on topic. No spam.

You can use these tags:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="">

This is a Gravatar-enabled weblog. To get your own globally-recognized-avatar, please register at Gravatar.