Tweet about this on TwitterShare on Facebook22Share on Google+0Share on Reddit0Share on LinkedIn0

Although limited, the StageWebView class makes it possible for an app to directly call a JavaScript function embedded within an HTML page.

Let’s walk through the steps required to call a JavaScript function from ActionScript.

Flash iOS Apps CookbookThis tutorial is a previously unreleased recipe from Flash iOS Apps Cookbook and supplements the content found in Chapter 11, Rendering Web Pages.

Flash iOS Apps Cookbook provides the recipes required to build native iOS apps using your existing knowledge of the Flash platform. Whether you want to create something new or simply convert an existing Flash project, the relevant steps and techniques are covered, helping you achieve your goal.

Getting ready

You’ll need AIR 2.6 or above for this recipe.

From this recipe’s accompanying code bundle, open chapter11\recipe7\recipe.fla and use it as a starting point.

Bundled within the FLA’s AIR for iOS settings is an HTML file named index.html. Embedded within the HTML is a JavaScript function named setMessage(), which takes a string argument and writes it to the HTML page.

Sitting on the FLA’s stage is an input text field named inputField and a movie clip with an instance name of updateBtn. When the user taps the updateBtn movie clip, we’ll send any text within inputField to the HTML page’s setMessage() function.

View of your FLA's stage.

Essentially, we’ll write code to pass a message entered within the app directly to a StageWebView object’s HTML, where it will be displayed.

Before proceeding, use a text editor of your choice to familiarize yourself with the HTML and its JavaScript. It can be found at chapter11\recipe7\html\index.html.

Let’s go ahead and write this recipe’s ActionScript.

How to do it…

Perform the following steps:

  1. Create a new document class and name it Main.
  2. Add the following import statements and declare a StageWebView member variable:
    package {
    
      import flash.display.MovieClip;
      import flash.events.MouseEvent;
      import flash.filesystem.File;
      import flash.geom.Rectangle;
      import flash.media.StageWebView;
      
      public class Main extends MovieClip {
    	
        private var webView:StageWebView;
    		
        public function Main() {
          // constructor code
        }
      }
    }
  3. Within the constructor, load the local web page and listen for the updateBtn movie clip being pressed. Position the web page’s viewport below the movie clip:
    public function Main() {
      var url:File = File.applicationDirectory.resolvePath(
        "html/index.html");
    			
      webView = new StageWebView();
      webView.stage = stage;
      webView.viewPort = new Rectangle(
        0, 160, stage.stageWidth, stage.stageHeight-160);
      webView.loadURL(url.nativePath);
    			
      updateBtn.addEventListener(MouseEvent.MOUSE_UP, pressed);
    }
  4. Finally, add the updateBtn movie clip’s event handler. Within it, call the web page’s setMessage() JavaScript function, passing it any text entered by the user:
    private function pressed(e:MouseEvent):void {
      var message:String = encodeURIComponent(inputField.text);
      webView.loadURL(
        "javascript:setMessage('" + message + "');");
    }
  5. Save the class and name its file Main.as when prompted.
  6. Move back to your FLA and save it.
  7. Passing text to an HTML page.

  8. Publish the FLA and test it on your device. Enter some text into the input text field and tap the Update text button. The text will be sent to the HTML page where it will be displayed.

How it works…

ActionScript to JavaScript communication is performed via the StageWebView class’ loadURL() method. Once a page is fully loaded you can use the javascript: URI scheme to invoke any functions that are declared within a StageWebView object’s web page. Take a look at the following example:

webView.loadURL("javascript:doSomething();");

This will call a JavaScript function named doSomething().

Parameters can also be passed:

webView.loadURL("javascript:setName('Tom', 'Waits');");

The call above passes two strings to a setName() function – Tom and Waits.

For this recipe, the text entered by the user was passed to the HTML page’s setMessage() JavaScript function. First it was URL-encoded using Flash’s top-level encodeURIComponent() function:

var message:String = encodeURIComponent(inputField.text);
webView.loadURL("javascript:setMessage('" + message + "');");

All strings passed from ActionScript to JavaScript should be URL-encoded, since certain characters, such as spaces, can cause problems for the StageWebView object’s URL parser. This is a common mistake and can be difficult to track. Take the following call as an example:

webView.loadURL("javascript:setMessage('Hello World');");

This will fail due to the un-encoded space within the string Hello World. The following is correct:

var message:String = encodeURIComponent("Hello World");
webView.loadURL("javascript:setMessage('" + message + "');");

Be careful when making calls to JavaScript. No errors are thrown if the function you are calling doesn’t exist or throws a run-time error. Your call will simply silently fail, making debugging difficult.

It’s also not possible to directly receive a return value from a JavaScript function using loadURL(). You’ll need to apply a little creative coding if you want to receive data from the JavaScript-side. Take a look at the next recipe, JavaScript to ActionScript communication, for more detail.

There’s more…

Here’s some additional detail.

Calling in response to page events

For this recipe we made our JavaScript call in response to the user pressing a button. It is however, perfectly acceptable to make a call as soon as an HTML page loads by listening for either Event.COMPLETE or LocationChangeEvent.LOCATION_CHANGE being dispatched by the StageWebView object.

Calling built-in JavaScript functions

It’s not possible to directly invoke JavaScript’s built-in functions using the loadURL() method. For example:

webView.loadURL("javascript:alert('Hello World');");

This line of ActionScript will not force an alert dialog to appear within the StageWebView. Instead the alert() would have to be placed inside a custom function that exists on the page.

JavaScript injection

JavaScript injection cannot be performed using the loadURL() method either. Take a look at the following:

webView.loadURL("javascript:var name='Christopher';");

The above attempt will fail to declare and initialize a variable called name.

See also