Understanding Flash's ExternalInterface.

It occurs to me that too many people are not aware of the Flash 8 new and shiny ExternalInterface and are still using fscommand and setVariable or getURL for flash-javascript communication.
In this post I’ll describe the advantages of ExternalInterface over the previous solutions, how to use it, a short tutorial about it, and also about the future of Flash-to-Javascript symbiosis with FABridge. Bear in mind that the ExternalInterface Class can be used to communicate from a flash-swf file to any kind of a supported container, in this text I will focus on a webpage container and we’ll connect to its Javascript functionality. We could, for example, use it in a similar way to communicate between Flash hosted inside an executable and its C# functionality.

Why should I care ?!

There are many reason to use Flash-Javascript communication, the more general ones are: using functionality that doesn’t yet implement naturally into Flash like XPath, REgEx, etc’. Controlling other webpage elements, active-x or plugin, from Flash. For example: Window Media Active-x. Using Flash with AJAX, and much more.
Check Step by step tutorials at the bottom of this text.

ExternalInterface minimum requirements

The ExternalInterface Class is only available from Flash 8 and above and will work only in Flash Player 8 and above. Also, there is a minimum browser requirement, the supported are:

Windows Internet Explorer 5.0 and above
Firefox 1.0 and above
Mozilla 1.7.5 and above
Netscape 8.0 and above
Safari 1.3 and above.
Opera 9 and above.
And any browser that supports the NPRuntime API.

The static Boolean property ExternalInterface.available will indicate whether the requirements are meet. Check it from within your targeted container / browser.
Click on the button, if it’s ‘false’ then your browser is probably not supported, if it’s ‘undefined’ then your player is probably less then version 8, if it’s ‘true’ you’re ready to go!

movie=”/content/images/2006/06/ExternalInterface_available.swf” height=”90″ width=”290″  

If you’re targeting a not supported browsers or an older Flash players, then you may consider: Flash / JavaScript Integration Kit

Main improvements:

Easier to setup: Well, that’s an understatement, in order to make your flash ready for javascript communication you need to do…, nothing. But, because of the new Flash 8 Player security you can’t test your files locally. Meaning that, the files will only run properly on a web server. If you want to test your files locally, all you have to do is make sure that the “allowScriptAccess”; is set to “always”; inside your html Flash <object> tag, like this:
<param name=”allowScriptAccess” value=”always” /> to support firefox and alike change also the <embed> tag: allowScriptAccess=”sameDomain” to “always”.
If you’re using swfobject your script will look something like this:
so.addParam(“allowScriptAccess”, “always”);. This also won’t guaranty that your files will work locally in all cases, though. You might also need to go to the Flash Player Setting Menager and add the swf files or folder as trusted. Here is a video demo on how to do that.
In Flash 6, 7 some Javascript and Vbscript functions had to be written in order to catch the fscommand calls from Flash. Flash 7 and above can insert these function automatically for you if you choose: Publish Settings… -> HTML -> Template->’Flash with FSCommand’. But it’s still ugly.

Synchronous: Which mean you can return a value from a Javascript function into flash and vice versa. If you ever used flash-to-javascript communication before flash 8, you’ll understand how useful this is. On previous versions of Flash this couldn’t be done. In order to receive data from javascript, we had to call a javascript setVariable, and that only worked on Object’s/MovieClip’s dynamic properties, and then we had to watch / wait for the data that was written into the MovieClip’s property to arrive to Flash. As opposed to now, communication was asynchronous, the data just wasn’t available instantly, and since the Object.watch sux so much in Flash 7. onEnterFrame or intervals had to be used. (I’ll admit that the Object.watch can be suitable in simple cases, though)

Calling Actionscript functions from Javascript:
Again, an amazing improvement. Now, any declared Flash function can be called directly from javascript with a simple script like flashMovie.someFunction(); and if this function returns a value it can be synchronously received by the browser’s Javascript. Before Flash 8, if we wanted something done inside flash and do it from javascript, calling a flash function for example, we had to set up a flag and go through a similar process as described above, of waiting/watching for that flag/data to arrive into Flash. Then according to that flag call the desired function.

Multiple Variables: ExternalInterface enable us to send or receive as many arguments as we want or send none. With the old fscommand only 1 and at least 1 string could have been sent to a javascript function.

Multiple Data types: ExternalInterface supports, sending and receiving, arguments of type: Boolean, String, Number, Array, Object (user defined classes are not supported). Sorry to be dramatic again but this has almost brought tears of joy to my eyes. All this time we had to use nothing more then one lousy String.

How to use the ExternalInterface Class

Calling is easy, Use the static ExternalInterface.call() function.

import flash.external.ExternalInterface;

ExternalInterface.call("alert", "called from flash");

This will call the javascript’s ‘alert’ function with the value of “called from flash”

For me, this is the most important improvement: Synchronous. If the Javascript function return a value you can simply retrieve it as follows (in this example it’s a Number but it can be any of the supported types):

var nValue:Object = ExternalInterface.call(“someJSFunction”&#157;);

To declare a Flash function as callable from Javascript you simply use the static ExternalInterface.addCallback() function.

The addCallback static method accepts 3 arguments. The first is a string representing the name, the Actionscript function should be called at, from Javascript. The second is an object reference for the Actionscript function, it’s where the scope of “this” inside the Flash function will be. The third is a reference to the Flash function. It is recommended to name the Javascript function the same as the real Flash function for sake of clarity.

ExternalInterface.addCallback(“someFlashFunction”&#157;, this, someFlashFunction);

Use this Javascript code to get a reference to your Flash movie.

“flashMovieID” is the ID of the Flash movie object inside the HTML.

<script><!--  
flashMovie = thisMovie("flashMovieID");

function thisMovie(movieName) {  
 var isIE = navigator.appName.indexOf("Microsoft") != -1;
 return (isIE) ? window[movieName] : document[movieName];
}
//call the Flash function
flashMovie.someFlashFunction();  
// --></script>

If the Flash function returns a value you can retrieve it as follows, as you might guessed:
var oValue = flashMovie.someFlashFunction();

Step by Step Tutorials for ExternalInterface

I will publish some step by step tutorials with in-depth explanation, source code and images in the next posts. I want to keep this post more concise. (or maybe I’m just too lazy right now… ;))

Among the tutorials will be:

Best way to get browser’s address variables into Flash.
Controlling another Active-X control – creating flash buttons for Windows Media Player or Apple Quicktime.
Putting Javascript power in Flash’s use – RegEx and XPath.
Catching Javascript Exceptions in Flash.
Creating, a, dynamic Flash website with AJAX.

Examples

Download ExternalInterface availability check

The Flash 8 IDE Installation will install two examples of using the ExternalInterface including the FLA sources. But, it doesn’t work locally because they forgot to update the html <object> "allowScriptAccess"; to "always";. If you want to check these examples locally simply change the word "sameDomain" wherever it appear (change it twice: one for the object param and one for the embed param) to “always” from within the html files. If it’s still doesn’t work go to the Flash Player Setting Menager and add the swf files or folder as trusted. As described above under Easier to setup:

Find the examples here:
In Windows, browse to boot drive Program Files/MacromediaFlash 8 Samples/ and TutorialsSamplesActionScriptExternalAPI.
On the Macintosh, browse to Macintosh HD/Applications/Macromedia Flash 8/Samples and Tutorials/Samples/ActionScript/ExternalAPI.

The future of Flash-Javascript symiosis with FABridge

Adobe wants to make Flash an IDE independent platform. Which means we’ll be able to create Flash RIA websites and application without the need of Adobe Flex Builder, Using the free Flex SDK, free Flex Data Services and any other third party software. Adobe relized that in order to make Flash the dominant force behind the rich web they have to free it from the restraints of any Flash/Flex IDE. And to leave it solely in the hand of the Flash/Flex developer. Adobe wants to make the Flash Platform as standard as HTML is.

With FABridge and alike, after the Flex Builder IDE was removed from the equation, the aim is to reduce the need for the Flex developer. With the insertion of the FABridge library into your Flex project you are completely exposing all the Actionscript 3.0 capabilities to Javascript. Basically you can code complete Flex apps using nothing but Javascript. This will appeal to Javascript developers who are comfortable with it and don’t want to develop simultaneously in both Flex and Javascript environments. FABridge will enable us to take full AJAX websites and Frameworks and easily update it to a full Flex websites or Frameworks to harness all the Flash platform capabilities.

FABridge is availble in pre-alpha since march 2006, so there is already some info about it circling around:
Last Friday I saw the online Adobe event “Flex and Ajax – Better Together” with James Ward. While it was mostly about how much superior Flex is from AJAX, he did showed a few integration / FABridge examples.
A similar presentation by Christophe Coenraets is availble here, with some more FABridge examples.

Go here to download FABridge and get some more info about it. Also check this impressive example that only scratch the surface. (require Flash Player 9).

Guy A

Read more posts by this author.