AIR: How to save locally a resource from Web
I am working on a very, very cool AIR project. I can’t say much about it for now, but in a couple of weeks I hope it will be released, and then I will blog about it. Anyway, while working on this project I had to implement different work flows revolving around online/offline status. One thing you often want to do in an AIR application is: save resources from the web to the local machine, either to make them available to the application even when a network connection isn’t available or just to optimize bandwidth usage.
That’s what this article is about. I will show you a simple snippet of code that just does the job. Here is the exported AIR project (download it, and you can import the archive using Import > Flex Builder > Flex Project) and here is the the application code:
<?xml version="1.0" encoding="utf-8"?> <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="init()"> <mx:Script> <![CDATA[ import mx.controls.Alert; /** * loader object used to load content from web */ private var loader:URLLoader = new URLLoader(); /** * This function gets called when the application was loaded. * Initialize the loader object. */ private function init():void { //we want to download images and other binary resources, //so I overwrite the default value text to Binary loader.dataFormat = URLLoaderDataFormat.BINARY; //attach the event listeneri for load event and errors event loader.addEventListener(Event.COMPLETE, onLoad); loader.addEventListener(IOErrorEvent.IO_ERROR, onError); loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onError); } /** * This is the click handler for the button in page. * Just triger the load and disable the button so no other * request can be sent while it is already running one. */ private function saveResource():void { loader.load(new URLRequest(resURL.text)); btn.enabled = false; } /** * This function gets called when the resource was loaded. * We just extract the name of the resource and call the saveLocally() function * to write the object on the local machine. */ private function onLoad(event:Event):void { btn.enabled = true; //enable the button so we can send another request. var fileName:String = new String(resURL.text).split("/").pop(); //call the saveLocally function; loader.data has the bytes of the loaded resource saveLocally(fileName, loader.data); } /** * Error handler for loader object. * I just display the error message and enable the button for new requests. */ private function onError(event:ErrorEvent):void { btn.enabled = true; Alert.show(event.text, "Error"); } /** * This function does the actual saving. * @param file name to be used for saving * @param bytes to be written */ private function saveLocally(fileName:String, data:ByteArray):void { //create a file under the application storage directory using the filename argument var file:File = File.applicationStorageDirectory.resolvePath(fileName); if (file.exists) file.deleteFile(); //delete it if exists //create a file stream to be able to write the content of the file var fileStream:FileStream = new FileStream(); //open the file stream and set for Write fileStream.open(file, FileMode.WRITE); //writes the bytes fileStream.writeBytes(data, 0, data.length); //close the stream fileStream.close(); //display the path of the saved resources showLocalPath.text = file.nativePath; } ]]> </mx:Script> <mx:VBox width="820" x="10" height="200" y="10"> <mx:Label text="Save a web resource locally" fontSize="26"/> <mx:Label text="Enter a resource URL such as http://mysite/image.jpg" /> <mx:HBox> <mx:TextInput id="resURL" text="" width="600"/> <mx:Button id="btn" click="saveResource()" label="Save locally" /> </mx:HBox> <mx:Label id="showLocalPath" /> </mx:VBox> </mx:WindowedApplication>
Here is an explanation of what I did:
- To getting the resource from the web, I use URLLoader. This object has a property that I can set to control how the resource is loaded: dataFormat. Since I want to download binary objects such as images and movies, I set this property to URLLoaderDataFormat.BINARY. Next, I attach some functions to my loader for Complete and Error events.
- When the resource is loaded, the onLoad function gets called and I can use the data loaded to create a file locally. I have access to loaded data using the loader.data property. This property gives me a ByteArray.
- Having the data, I can write the file using the AIR API. I use File.applicationStorageDirectory.resolvePath(”file name”) to create a file in the Application storage folder. I write to this file using a FileStream.
- The rest of the code is just a simple UI: a text input to let the user to enter the URL for the resources, a button to execute the code, and a label that displays the path to the saved file.
Comments
2 Responses to “AIR: How to save locally a resource from Web”
Leave a Reply
I set this property to I attach some functions to my loader for Complete and Error events.
[...] You can read more on this here. [...]