A multiple file loader for Flex/Flash/ActionScript 3 (AS3)


The URLMultiLoader class in this library will load multiple files and optionally “process” them before calling the method specified for Event.COMPLETE. Since file loading in the Flash/Flex/AS3 world is completely asynchronous, when you need to load more than one file, the hackish solution is to make the COMPLETE handler for the first one initiate the load for the second, etc. until all the files are loaded. URLMultiLoader will allow you to setup one COMPLETE handler which will not be called until all the files you specify are loaded (and optionally “processed”).

When I first had need for this, I said to myself that someone must have done this before. It seems like a fairly common need. However, when I went looking, I couldn’t find something that fit the bill, so I decided to write my own. It was actually a very good way to get familiar with the event system. Also, while I was at it, I figured I’d allow the injection of a processor for each file and make sure that got processed before proceeding. If anyone knows of another tool like this please post a link to it in the comments. Actually, it wouldn’t surprise me if this functionality is built into the Flex framework somewhere and I just missed it.

Update: The functionality mustn’t be in Flex because I have now found several other similar controls:

Mine is relatively simple compared to some of these. BulkLoader seems particularly featureful. It has bandwidth stats and progress indicators. For my loading needs, the sizes were small enough that I wasn’t worried about progress or bandwidth, but I may update mine to include these features in the future.

One feature that mine has that many do not have is the optional ability to inject in a an IDataProcessor that will pre-process your data before returning it to you.

DataProcessorXMLStringToArray is provided as an example IDataProcessor that can optionally be passed in when adding a new URLRequest to the queue. If provided, an IDataProcessor will convert the raw file string (or binary, or url variables) into some other form before returning. Complete documentation for DataProcessorXMLStringToArray is provided in the ASDoc header for the class but it is offered here primarily as an example. You can easily create your own and inject them when setting up the URLMultiLoader. You just need to follow the IDataProcessor interface which has one method with the following signature:

function processData(data:*):*

Remember, the processor is totally optional. If omitted, URLMultiLoader will simply copy the file contents into it’s output data field. The type of the data in that case will depend upon the URLLoaderDataFormat: String for TEXT (default), ByteArray for BINARY, and URLVariables for VARIABLES.

Let’s see it in action.

package
{
	import com.maccherone.urlmultiloader.*;
	import com.maccherone.json.JSON;  // Only used for pretty output
 
	import flash.display.Bitmap;
	import flash.display.Loader;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.IOErrorEvent;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
 
	public class URLMultiLoaderTest extends Sprite
	{
		private var urlMultiLoader:URLMultiLoader = new URLMultiLoader()
		private var baseURL:String = "data/"
		private var urlRequest1:URLRequest = new URLRequest(baseURL + "file.xml")
		private var urlRequest2:URLRequest = new URLRequest(baseURL + "file.xml")  // Same file but we'll get it in a different format
		private var urlRequest3:URLRequest = new URLRequest(baseURL + "smile.gif")
 
		public function URLMultiLoaderTest() {
			var urlMultiLoader:URLMultiLoader = new URLMultiLoader
 
			var dataProcessor:IDataProcessor = new DataProcessorXMLStringToArray()  // Example provided with URLMultiLoader. You can create your own.
 
			urlMultiLoader.addURLRequest("Request1", urlRequest1, dataProcessor)
			urlMultiLoader.addURLRequest("Request2", urlRequest2)  // If no IDataProcessor is provided, then file's contents is returned as String, ByteArray, or
			                                           // URLVariables depending upon the URLLoaderDataFormat TEXT, BINARY, or VARIABLES respectively
			urlMultiLoader.addURLRequest("Request3", urlRequest3, null, URLLoaderDataFormat.BINARY)  // Loads smile.gif as a ByteArray
 
			urlMultiLoader.addEventListener(Event.COMPLETE, filesLoaded)
			urlMultiLoader.addEventListener(IOErrorEvent.IO_ERROR, onError)
			urlMultiLoader.load()
		}
 
		private function filesLoaded(event:Event):void {
			var data:Object = (event.target as URLMultiLoader).data
			trace("Array of Objects:\n" + JSON.encode(data["Request1"], true) + "\n") // Uses JSON.encode for pretty output
			trace("String of file contents:\n" + data["Request2"] + "\n")
			var loader:Loader = new Loader();
			loader.loadBytes(data["Request3"]);
			this.addChild(loader)  // Displays smile.gif in Flash player
		}
 
		private function onError(event:Event):void {
			trace(event)
		}
	}
}

Assuming you put the file.xml and the smile.gif , in a data/ folder below the bin-debug directory and you have the correct security settings, the above code would result in the following output:

Array of Objects:
[
    {"id": 101, "name": "/db/node/visitor"},
    {"id": 102, "name": "/db/node/observer"},
    {"id": 103, "name": "/ui/button"}
]
 
String of file contents:
<?xml version="1.0" encoding="UTF-8"?>
<root>
  <file>
    <id>101</id>
    <name>/db/node/visitor</name>
  </file>
  <file>
    <id>102</id>
    <name>/db/node/observer</name>
  </file>
  <file>
    <id>103</id>
    <name>/ui/button</name>
  </file>
</root>

Plus it will display smile.gif in the Flash player like this:

smile_in_flash_player

You can download it from here.

Update: I altered the URLMultiLoader to use a string as the key to retrieving the data after the loading is complete. A previous version used the URLRequest as the key for Dictionary object. This version does not depend upon Dictionary.

 

This entry was posted in Code, Flex/Flash/ActionScript and tagged , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *

Spam Protection by WP-SpamFree