Getting data into flash: swfobject 2 and ExternalInterface (as3)

Using swfobject v.2 is a great way to embed your swf and pass it flash variables, but to pass it a data object, you would use javascript and connect it to the ExternalInterface from the flash. There I ran into a snag.

The snag being that it didn’t work anymore. When I added the callback – in actionscript: ExternalInterface.addCallback – and called it from a window.onload event in javascript, it no longer worked; nor did it with the callback function in swfobject 2. It used to work in earlier versions. The documentation on Google only points to the static replacement technique (works), but I really don’t want to use that method. The 9.0/ActionScriptLangRefV3/" rel="external">Adobe documentation uses a timer, checking javascript availability from the flash – which I thought was too complex and verbose, just for demonstration purposes. But I used this method anyway; I did shorten it a bit.

Anyhoo – here’s how I got it to work. Roughly:

  • there’s an object with data available in your javascript: for example getDataObj() constructs and returns an object with data
  • swfobject.embedSWF replaces a DOM-element with the swf-object on the page
  • the swf loads, and starts waiting for data with the callback function eiDataReceiver
  • the swf calls javascript to see whether the function onSwfLoaded() is available (so no need for window.onload function)
  • this onSwfLoaded() calls the actionscript function eiDataReceiver that passes it the data-object
  • tada, the swf starts up with a restored data set.

The example below is used to get data from javascript into the swf, implementing swfobject 2 dynamic replacement and AS3 ExternalInterface.

in actionscript:

3; auto-links: false;">
import flash.external.*;
import flash.utils.Timer;
//
private function checkForJSData():void{
	//add callback to receive data from javascript
	if(ExternalInterface.available) {
		try{
			trace('inside try EI');
			ExternalInterface.addCallback("eiDataReceiver", onReceivedFromJavaScript);
			if(!jsReadyState()) checkForJavascript();
		}catch(err:Error){ 
			trace("An EI error occurred: " + err.message + "\n"); 
		}
	}
}
//
private function checkForJavascript():void{
	var readyTimer:Timer = new Timer(50, 0);
	readyTimer.addEventListener(TimerEvent.TIMER, timerHandler);
	readyTimer.start();
}
private function timerHandler(evt:TimerEvent):void {
	var isReady:Boolean = jsReadyState();
	if (isReady) Timer(evt.target).stop();
}
private function jsReadyState():Boolean{
	var readyState:Boolean = ExternalInterface.call("onSwfLoaded");
	return readyState;
}
private function onReceivedFromJavaScript($obj:Object):void {
	if($obj!=null) GlobalVars.jsData = $obj;
}

in javascript:

//replaces element with id "circlegame" with flash object 
var flashvars = {xmlUrl: "swf/data/colorset_01.xml", debugMode: "on"};
var params = {wmode:"opaque", allowscriptaccess:"always" };
var attributes = {id:"circlegame",  name:"circlegame"};
//
swfobject.embedSWF("swf/netwerkcirkels.swf", "circlegame", "940", "540", "9.0.0", "swf/expressinstall.swf", flashvars, params, attributes);
//
function onSwfLoaded(){
	//calls AS fuction "eiDataReceiver" in the swf and passses the data to it
	document.getElementById("circlegame").eiDataReceiver( getDataObj() );
	//notify flash that js has loaded:
	return true;
}

The function getDataObj() is not included in this example; it constructs and returns an object with data, which immediately can be used by the actionscript without having to parse it.

1

in snippets+

post a commentsave the linkrate as favorite

leave a comment

Your e-mail address will not be made public or shared with others. Required fields are marked with a *

*
*

Optionally, you could use these HTML tags: <b> <cite> <code> <i> <strike> <strong>