Accessibility
Jonathan Duran

Jonathan Duran

Adobe

Created:
20 March 2006
User Level:
Intermediate, Advanced
Products:
Devices

Loading, Parsing, and Locally Storing XML in Flash Lite 2

Two of my favorite new features in Flash Lite 2 are the ability to load and parse XML and to store data locally on a device. In this article I'll show you how to create a simple Flash Lite application (see Figure 1) that loads XML updates and stores them in a Flash Lite shared object.

Quote and citation application running on the emulator

Figure 1. Quote and citation application running on the emulator

Requirements

To follow this tutorial you will need to install the following software and files:

Flash Professional 8

Flash Lite 2 Update for Flash Professional 8

Download the update in the Support Center.

Sample files:

Prerequisite Knowledge

Before reading this article, you should be familiar with the Macromedia Flash Professional 8 authoring environment and mobile emulator. For information on getting starting with Flash Lite and mobile authoring using Flash 8, please refer to the mobile features page for Flash 8 and the Flash Lite Developer Center.

To use the source code and materials in this article, you will need Flash 8 Professional and the Flash Lite 2 Update for Flash Professional 8. You can run the files in the Flash 8 mobile emulator. However, to experience the actual application performance and user interaction, you will also need a device that supports the Flash Lite 2 player.

The XML

First let's take a quick look at the XML to get an idea of what will be required of the interface. I created a simple XML file that holds a quote and its citation:

<review>
    <review_item citation="Citation here">
        Quote here.
    </review_item>
</review>

As you can see, there is a root node called review and then a review_item, which contains the data. The quote is text data for the node; the citation is an attribute.

The Interface

The first step in setting up the sample file is to create the interface. The movie is split into two application states in the timeline: a default state displaying the XML data (see Figure 2) and a "wait screen" state for when the XML data is being updated (see Figure 3).

Default state and its content

Figure 2. Default state and its content

Wait-screen state and its content

Figure 3. Wait-screen state and its content

The loaded XML file contains two pieces of data: a quote and its citation. I placed two dynamic text fields on the Stage in Frame 1 to display the data. The only other elements on Frame 1 are the background graphics and static text over the soft keys to indicate "Update" and "Quit." The wait-screen state contains only static graphics and text.

The Code

Now let's take a look at the code that parses the XML and stores the data. All the code for the sample is in the first frame of the main Timeline. The wait screen contains no code and exists only to give the Flash content some time to parse the updated XML and assign the data to the text fields. I found that trying to do the loading, parsing, and updating of XML data in one frame on slower devices caused the variables not to become set in time.

The first bit of code in Frame 1 sets up the SWF to run full-screen and use the soft keys, and defines the behavior for the soft keys:

// set content to full screen and initialize soft keys for use
fscommand2("fullscreen", true);
fscommand2("SetSoftKeys", "Left", "Right");

// ===== Set listener for soft keys =====
globalKeyListener = new Object();
globalKeyListener.onKeyDown = function() {
    if(Key.getCode() == ExtendedKey.SOFT2) {
        // actions for right soft key
        fscommand2("quit");
    } else if (Key.getCode() == ExtendedKey.SOFT1){
        // actions for left soft key
        checkForUpdateXML();
    }
}
// Add the handler for the soft keys
Key.addListener(globalKeyListener);

To use the soft keys in Flash Lite 2, listeners are required. The listener for the soft keys in the previous code is an object called globalKeyListener with a function called onKeyDown attached. This is an event specific to the Key object in Flash, which has been extended to include "SOFT1" and "SOFT2" to listen for the soft keys. The two soft keys allow users to update their quote or quit the application. If they choose to update, the checkForUpdateXML() function is called, which I'll go over in a moment.

The next code creates functions to handle local storage and initializes the Flash Lite shared object:

// ===== Setup and initialize the SharedObject =====
var soReady:Boolean = false; // flag for SharedObject readiness

// Handler function for when the SharedObject is initialized
function soInitHandler(instance:SharedObject) {
    soReady = true;
    if(so_reviews.data.firstRun == undefined){
        initialXML();
    } else {
        getSOdata();
    }
}
// Function to write data to the SharedObject
function setSOdata(){
    if (soReady){
        so_reviews.data.review = reviewData.toString();
        so_reviews.data.citation = citationData.toString();
        so_reviews.data.firstRun = true;
        so_reviews.flush();
        trace(so_reviews.getSize());
        trace("First time app is run - default data saved");
    } else {
        trace("ERROR: SharedObject not ready. No data written.");
    }
}
// Function to display the data from the SharedObject
function getSOdata(){
    if (soReady){
        citation_txt.text = so_reviews.data.citation;
        review_txt.text = so_reviews.data.review;
        trace("Not first time app was run - SharedObject data displayed");
    } else {
        review_txt.text = "Data not available.";
    }
}
// Add the handler for initialization then create the SharedObject
SharedObject.addListener("reviews", soInitHandler);
var so_reviews:SharedObject = SharedObject.getLocal("reviews");

The first line creates a variable that I use as a flag to check whether the shared object has been created and is ready for use. I then create three functions to handle the shared object: soInitHandler(), setSOdata(), and getSOdata():

  • soInitHandler() is the callback function for when the shared object gets created. It's the first function that the shared object runs after it instantiates, and all it does is check to see whether this is the first time the shared object has been created. If it is, it calls a function called initialXML() to parse the default set of XML. If it's not the first time the application has been run, then getSOdata() is called to use the existing data from the shared object.
  • setSOdata() is the function that takes new data and pushes it into the shared object. It checks to see whether the shared object is ready, using the flag I created. If it is, it assigns the XML data to the data property of the shared object and then flushes it. I don't need to flush the data explicitly here because it should be saved on exit; I do this just to make sure it gets saved and to demonstrate the methods of the shared object.
  • getSOdata() is the function that takes the data from the shared object's data property and assigns it to the text fields on the Stage. It gets called from the soInitHander() if the application has been run before and has data.

The last couple of lines of code in this section add the init listener and then instantiates the shared object.

The rest of the code in the application is the code that actually loads and parses the XML:

// ===== Functions for loading and parsing the XML =====
// Function to retrieve the default set of XML data
function initialXML(){
    reviewXML = new XML();
    reviewXML.ignoreWhite = true;
    reviewXML.onLoad = function(success){
        if(success){
            reviewXML = reviewXML.firstChild;
            if(reviewXML.nodeName.toUpperCase() == "REVIEW"){
                reviewData = reviewXML.firstChild.firstChild;
                citationData = reviewXML.firstChild.attributes.citation;
                review_txt.text = reviewData;
                citation_txt.text = citationData;
            }
        } else {
            trace("connection failed");
        }
        setSOdata();
    }
    reviewXML.load("initial.xml");
}
// Function to check for updated XML data
function checkForUpdateXML(){
    updateXML = new XML();
    updateXML.ignoreWhite = true;
    updateXML.onLoad = function(success){
        if(success){
            updateXML = updateXML.firstChild;
            if(updateXML.nodeName.toUpperCase() == "REVIEW"){
                reviewData = updateXML.firstChild.firstChild;
                citationData = updateXML.firstChild.attributes.citation;
                review_txt.text = reviewData;
                citation_txt.text = citationData;
            }
        } else {
            trace("connection failed");
        }
        setSOdata();
        gotoAndPlay("waitscreen");
    }
    updateXML.load("updated.xml");
}
stop();

There are two functions defined in this section: initialXML() and checkForUpdateXML():

  • initialXML() gets called only once in the lifetime of the application, which is the first time it is run. This function loads some default XML from the local file system. The function first creates a new XML object called reviewXML to work with and tells it to ignore white space in the XML file. Then an onLoad function is defined that gets called automatically once the XML data has completed loading.

    This is where the XML is parsed into variables for Flash. First I pass the firstChild of reviewXML to itself so that I can get to the root node of the XML, called "review." If the root node name is the one I expect, then I assign the XML data and attributes to the variables and then to the text fields on the Stage to display the information to the user. I then call the setSOdata() function to store the information in a shared object so I won't have to load it the next time the application is run. The last thing the function does is actually load the XML file, which triggers the onLoad handler.

  • checkForUpdateXML() is run whenever the user presses the left soft key. This function is similar to the initialXML() function. It creates a new XML object called updateXML to work with and tells it to ignore white space in the XML file. It then defines its onLoad handler, which does the exact same thing as initialXML(). The only difference here is that as soon as I set the data by calling setSOdata(), I also send the timeline to the wait screen state, which allows Flash Lite time to load the XML and flush the information to memory. The wait screen plays through and the application loops back to the first frame.

    I'm also loading the XML from a different location. In an actual application this would probably be some XML from the web. You can try uploading the update.xml file to your web server and using the URL in the load method instead of the local relative path, which should work just the same. When the application gets back to the first frame, it checks to see if it's running for the first time. When it finds that it's not, it pulls the freshly updated XML data out of the shared objects and displays it for the user.

That's all there is to it! You should now know how to parse some XML in Flash Lite 2 and store it to the handset.

About the author

Jonathan Duran has been working at Adobe for more than six years and is currently a Senior QE Engineer for Flash authoring. Prior to that, Jonathan supported the developer community in a range of positions including Developer Relations for Mobile and Devices, Flash technical support, Developer Center Editor, and Developer Relations for Macromedia Central. Jonathan loves building mobile applications and doing development in Flash, but he often prefers backpacking in the Yosemite wilderness, composing electronica, playing Canasta, and feeding catnip to his cat, Mingatsu Takahashi.