I searched forever on trying to find a good way to preload an external SWF in AS3 while passing through external FlashVars. I finally saw this post and it worked perfectly!
http://www.zedia.net/2008/external-preloader-more-complex-cases/
The trick is writing an Interface – in this case it’s a way of having the preloader call the init function of the main document class without requiring all of the internal linked assets of the SWF. The main document class then implements the interface (shown below).
So I just wrote an Interface that has an init() method with each of my FlashVars as arguments:
MyFlashApp_Interface.as
package {
public interface MyFlashApp_Interface{
function init(externalArg1:String, externalArg2:String):void;
}
}
Then in my preloader I can import it and use it for casting. This can be done in a frame script.
MyFlashApp_loader.fla (Frame 1 Script)
import MyFlashApp_Interface;
var l:Loader = new Loader();
l.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, loop);
l.contentLoaderInfo.addEventListener(Event.COMPLETE, done);
l.load(new URLRequest("MyFlashApp.swf"));
function loop(e:ProgressEvent):void
{
var perc:Number = e.bytesLoaded / e.bytesTotal;
loadBar.gotoAndStop(Math.ceil(perc*100));
}
function done(e:Event):void
{
// cast the loader content as MyFlashApp_Interface interface
var mainContent:MyFlashApp_Interface = MyFlashApp_Interface(l.content);
addChild(Sprite(mainContent) );
mainContent.init( String(root.loaderInfo.parameters.externalArg1),
String(root.loaderInfo.parameters.externalArg2) )
}
stop();
Then in my main class, I implement the interface and have some extra stuff in the constructor so it will initialize correctly when placed on the stage using addChild. Also I put in a check to prevent the init() function from being called more than once:
MyFlashApp.as
public class MyFlashApp extends Sprite implements MyFlashApp_Interface {
public var externalArg1:String="default_value";
public var externalArg2:String="default_value";
private var inited:Boolean=false;
public function MyFlashApp():void {
if(stage!=null) {
// stage will be null when this movie is loaded externally
// otherwise call the _init function
_init();
}
}
public function init(_externalArg1:String, _externalArg2:String):void{
// this function is called by the MyFlashApp_Interface interface
// when this SWF is loaded externally
if(_externalArg1!="undefined")
externalArg1=_externalArg1;
if(_externalArg2!="undefined")
externalArg2=_externalArg2;
_init();
}
// internal init function
private function _init(evt:Event=null) {
if(!inited) {
inited=true;
// initialize code goes here
}
}
}

