AS3 - How to load and read XML file on iOS - ios

I'm working on simple iOS game where you have e.g. 10 levels and once you completed one the next level will unlock. I create the xml file here:
private function SaveProgress()
{
addChild(myTextField);
var GameSaveXML:XML =
<LEVEL>
<LEVEL_01>false</LEVEL_01>
<LEVEL_02>false</LEVEL_02>
<LEVEL_03>false</LEVEL_03>
<LEVEL_04>false</LEVEL_04>
<LEVEL_05>false</LEVEL_05>
<LEVEL_06>false</LEVEL_06>
<LEVEL_07>false</LEVEL_07>
<LEVEL_08>false</LEVEL_08>
<LEVEL_09>false</LEVEL_09>
<LEVEL_10>false</LEVEL_10>
</LEVEL>;;
//file.deleteFile();
var file:File = File.documentsDirectory.resolvePath("LevelsSaved.xml");
if (file.exists)
{
trace("EXISTS");
trace(GameSaveXML);
}
else
{
var fileStream = new FileStream();
fileStream.open(file, FileMode.WRITE);
var outputString:String = '<?xml version="1.0" encoding="utf-8"?>\n';
outputString += GameSaveXML.toXMLString();
fileStream.writeUTFBytes(outputString);
//GameSaveXML.replace(2,<LEVEL_03>true</LEVEL_03>);
trace(GameSaveXML);
fileStream.close();
trace("File Was Created");
}
}
I'm really struggling with loading the file and checking what levels are unlocked (true) and what levels are still locked (false). Can you please help? Thanks a lot!

If you know how to write xml, can't you read it the same way?
var content:String = fileStream.readUTFBytes(fileStream.bytesAvailable);
var xml:XML = new XML(content);
if (xml.LEVEL_01 == 'true') trace('unlocked');
else trace('locked');
or you can use URLLoader to load xml as string
I'm 99% sure I did not undestand the question - sorry then :p

Related

how to create .txt in local file system using Firefox extension

I am currently working on ffsniff extension code. In that I have to save data containing password information into a file in my local system. I have written my code but it is not even creating the file in my local system. (working in mozilla firefox)
Here is my code please help me out.
//// here data variable contains all the information
var fso = new ActiveXObject("Scripting.FileSystemObject");
varFileObject = fso.OpenTextFile("C:\\logs.txt", 2, true,0);
varFileObject.write(data);
varFileObject.close();
after this i tried different code:
Components.utils.import("resource://gre/modules/NetUtil.jsm");
Components.utils.import("resource://gre/modules/FileUtils.jsm");
var file = Components.classes["#mozilla.org/file/directory_service;1"].
getService(Components.interfaces.nsIProperties).
get("Desk", Components.interfaces.nsIFile);
file.append("logs.txt");
var ostream = FileUtils.openSafeFileOutputStream(file)
var converter = Components.classes["#mozilla.org/intl/scriptableunicodeconverter"].
createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
converter.charset = "UTF-8";
var istream = converter.convertToInputStream(data);
}
});
but none of them is working..
Here's a working snippet that creates the destination directory if necessary and writes (overwrites) to file (in this case d:\temp-directory\temp-file.txt):
var {Cc,Ci,Cu}=require("chrome"); //for jetpack sdk.
Cu.import("resource://gre/modules/NetUtil.jsm");
Cu.import("resource://gre/modules/FileUtils.jsm");
var localFile = Cc["#mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
var data="test file content";
//localFile.initWithPath("D:\\temp-directory\\temp-file.txt"); //full path is okay if directory exists
localFile.initWithPath("D:\\temp-directory\\"); //otherwise specifiy directory, create it if necessary, and append leaf.
if(!localFile.exists()){
localFile.create(localFile.DIRECTORY_TYPE,FileUtils.PERMS_DIRECTORY);
}
localFile.append("temp-file.txt");
//localFile.createUnique(localFile.NORMAL_FILE_TYPE,FileUtils.PERMS_FILE); //optional: create a new unique file.
asyncSave(localFile,data,onDone);
function asyncSave(file,data,callbackDone){
// file is nsIFile, data is a string, optional: callbackDone(path,leafName,statusCode)
// default flags: FileUtils.openSafeFileOutputStream(file, FileUtils.MODE_WRONLY | FileUtils.MODE_CREATE | FileUtils.MODE_TRUNCATE);
var ostream = FileUtils.openSafeFileOutputStream(file);
var converter = Cc["#mozilla.org/intl/scriptableunicodeconverter"].createInstance(Ci.nsIScriptableUnicodeConverter);
converter.charset = "UTF-8";
var istream = converter.convertToInputStream(data);
// optional: callbackSaved(status).
NetUtil.asyncCopy(istream, ostream, callbackSaved);
function callbackSaved (status) {
if(callbackDone){
if(status===0)callbackDone( file.path, file.leafName, status); //sucess.
else callbackDone( null, null, status); //failure.
};
}
}
function onDone(path,leafName,statusCode){
console.log([statusCode===0?"OK":"error",path,leafName].join("\n"));
}
More information:
https://developer.mozilla.org/en-US/docs/Code_snippets/File_I_O
https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/FileUtils.jsm
https://developer.mozilla.org/en-US/docs/PR_Open
https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/NetUtil.jsm
https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsIFile
https://developer.mozilla.org/en-US/docs/XPCOM_Interface_Reference/nsILocalFile
A simple example of how to read/write a file from the filesystem in windows, using Firefox Extension:
// Write File to filesystem
Components.utils.import("resource://gre/modules/osfile.jsm"); // load the OS module
var encoder = new TextEncoder(); // This encoder can be reused for several writes
var array = encoder.encode("just some text"); // Convert the text to an array
var promise = OS.File.writeAtomic("C:\\foo.txt", array,{tmpPath: "foo.txt.tmp"}); // Write the array atomically to "file.txt", using as temporary
alert("URL HOST has been saved");
//Read File from filesystem
var decoder = new TextDecoder(); // This decoder can be reused for several reads
var promise = OS.File.read("C:\\foo.txt"); // Read the complete file as an array
promise = promise.then(
function onSuccess(array) {
alert(decoder.decode(array)); // Convert this array to a text
}
);
This solution is for making file in ubuntu, hope this helps others:
var file = Components.classes["#mozilla.org/file/directory_service;1"].
getService(Components.interfaces.nsIProperties).
get("ProfD", Components.interfaces.nsIFile);
file.append("trick_new");
if( !file.exists() || !file.isDirectory() ) { // if it doesn't exist, create
file.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0777);
}
this.log_file = file.path + "/newlog.html";
You can also use text-stream to write to a local file.
function writeTextToFile(text, filename) {
var fileIO = require("sdk/io/file");
var TextWriter = fileIO.open(filename, "w");
if (!TextWriter.closed) {
TextWriter.write(text);
TextWriter.close();
}
}

Adobe AIR 3.4 saving/writing XML data to iOS

I'm trying save XML data to an iPad 4 with AIR 3.4 for iOS and really can't tell if this is working or not. No events are being fired apparently. Any help is greatly appreciated.
private function saveData(e:MouseEvent):void {
var name:String = AssetManager.SAVE_ANNOTATIONS_NAME
var file:File = new File()
file = File.applicationStorageDirectory.resolvePath(name + "xml");
var xml:XML = _canvas.getObjectData(FormatType.DEGRAFA);
var fileStream:FileStream = new FileStream();
fileStream.open(file, FileMode.WRITE);
fileStream.writeUTF(xml.toString());
fileStream.addEventListener(ProgressEvent.PROGRESS, onFileStream);
fileStream.addEventListener(Event.ACTIVATE, onFileStream);
fileStream.addEventListener(Event.OPEN, onFileStream);
fileStream.addEventListener(Event.DEACTIVATE, onFileStream);
fileStream.addEventListener(IOErrorEvent.IO_ERROR, onFileStream);
fileStream.addEventListener(Event.COMPLETE, onFileStream);
}
protected function onFileStream(event:Event):void
{
trace('filestream event was ' + event)
fileStream.close();
}
I seemed to have fixed it with this:
private function saveFile(event:MouseEvent):void
{
var xml:XML = _canvas.getObjectData(FormatType.DEGRAFA);
trace('xml is ' + xml.toXMLString())
var file:File = File.documentsDirectory.resolvePath("annotations.xml");
var fileStream:FileStream = new FileStream();
fileStream.openAsync(file, FileMode.WRITE);
fileStream.writeUTFBytes(xml.toXMLString());
fileStream.addEventListener(Event.CLOSE, fileClosed);
fileStream.close();
function fileClosed(event:Event):void {
trace("File Saved");
}
}
You are writing BEFORE adding the listeners. Proper order should be:
var fileStream:FileStream = new FileStream();
// all the listeners here
fileStream.open(file, FileMode.WRITE);
fileStream.writeUTF(xml.toString());
You must take note of the command you are using to open the file stream. If you use filestream.openAsync then the file stream is opened asynchronously, meaning you will have to wait for the Event.OPEN event on the filestream object. If you use filestream.open, then you can call functions on the filestream object immediately without waiting for an OPEN event. For me the jump to ActionScript, and its asynchronous nature, took some time to get used to.

Adobe AIR Mobile on iOS - processing text very slow

I am writing an iOS app in Flash Builder 4.6 that will need to process a large text file. So far, I am just trying to get the version information from the file, a simple task that runs very fast in the simulator but takes a very long time (on the order of 10 seconds) on my iPad 2.
As the file is large (about 11MB), I am trying to only read far enough into the file to get the version data. Is it possible that the filestream loads the whole file into memory anyway? If so, how do I avoid that?
Note that the code works correctly, and displays the correct version info.
Any advice on how to speed it up would be greatly appreciated.
The file being processed can be found here: http://oanda.sca.org:80/oanda.db
The code is as follows:
Calling code:
protected function view1_viewActivateHandler(event:ViewNavigatorEvent):void
{
var DT:DatabaseTools = new DatabaseTools();
var version:String;
//Get version information from local file:
version = DT.GetLocalVer("oanda.db");
lblLclVer.text=version;
}
Actual function:
public function GetLocalVer(fileName:String):String
{
var out:ByteArray = new ByteArray();
var line_Out:String;
var char:int;
var line:ByteArray = new ByteArray();
var stream:FileStream = new FileStream();
var file:File = File.documentsDirectory.resolvePath(fileName);
var lineString:String;
var result:String = "Error";
stream.open(file,FileMode.READ);
var found:Boolean=false;
while((stream.bytesAvailable > 0) && !found)
{
char=stream.readByte();
if(String.fromCharCode(char) == "\n")
{
//reset the line
out=line;
line = new ByteArray();
//process the line to see if its the version info.
lineString=out.toString(); //since the version line never has UTF characters, convert it to a regular string
if(lineString.length > 25) //Any line shorter than this can't be the version line
{
var startOfLine:String = lineString.substr(0,17);
if(startOfLine == " ||C|Last update:")
{
result = lineString.substr(19,6);
found = true;
}
}
}
else
{
line.writeByte(char);
}
}
stream.close();
return result;
}
Thanks.

WinRT StorageFile write downloaded file

I'm struggling with a easy problem. I want to download an image from web using this code:
WebRequest requestPic = WebRequest.Create(#"http://something.com/" + id + ".jpg");
WebResponse responsePic = await requestPic.GetResponseAsync();
Now I wanted to write the WebResponse's stream in a StorageFile (eg. create a file id.jpg in the app's storage), but I haven't found any way to achieve that. I searched the web for it, but no success - all ways incompatible Stream types and so on.
Could you please help?
I have found the following solution, which works and is not too complicated.
public async static Task<StorageFile> SaveAsync(
Uri fileUri,
StorageFolder folder,
string fileName)
{
var file = await folder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
var downloader = new BackgroundDownloader();
var download = downloader.CreateDownload(
fileUri,
file);
var res = await download.StartAsync();
return file;
}
You will need to read the response stream into a buffer then write the data to a StorageFile. THe following code shows an example:
var fStream = responsePic.GetResponseStream();
var file = await ApplicationData.Current.LocalFolder.CreateFileAsync("testfile.txt");
using (var ostream = await file.OpenStreamForWriteAsync())
{
int count = 0;
do
{
var buffer = new byte[1024];
count = fStream.Read(buffer, 0, 1024);
await ostream.WriteAsync(buffer, 0, count);
}
while (fStream.CanRead && count > 0);
}
That can be done using the C++ REST SDK in Windows Store Apps. It's explained by HTTP Client Tutorial.

save bmpData as jpg using adobe flex in air application

i use the following code:
protected function videoDisplay_playheadUpdateHandler(event:mx.events.VideoEvent):void
{
if(!captured && videoDisplay.playheadTime>=0){
capture();
}
}
private function capture():void
{
var bmpData:BitmapData = new BitmapData(videoDisplay.width, videoDisplay.height);
bmpData.draw(videoDisplay);
captured = true;
store(...); //????????
}
in order to capture a frame from a videoDisplay object
1) is it correct or am i doing something wrong?
2) what can i do to store the bmpData as .jpg at my computer?
i am using flex4.5 and it is an air app...
any ideas??
Thanks in advance!!
The following code should help you
var jpegEncoder:JPEGEncoder = new JPEGEncoder(90);
var jpgSource:BitmapData = new BitmapData(videoDisplay.width,videoDisplay.height);
jpgSource.draw(this);
var fileReference:FileReference = new FileReference();
fileReference.save(jpegEncoder.encode(jpgSource),"videoImage.jpg");
To use jpeg encode you need to have to import
import mx.graphics.codec.JPEGEncoder;
The above changes should be enough to allow the user to take a snapshot of a running video.
Please note, that with this the user will be prompted to select the location of the file.
Incase you want a silent save, let me know, I will put up the required code.
Somewhere in your application keep an image tag as follows.Most apt place should be just below the video.
<mx:Image scaleContent="true" width="150" height="120" maintainAspectRatio="false" id="myScaledSnapshot"/>
Now with this done, do the following changes in your code:
private function capture(filename:String):void
{
var bitmapData:BitmapData = new BitmapData(videoDisplay.width, videoDisplay.height);
bitmapData.draw(videoDisplay,new Matrix());
var bitmap : Bitmap = new Bitmap(bitmapData);
var jpg:JPEGEncoder = new JPEGEncoder();
var ba:ByteArray = jpg.encode(bitmapData);
myImageSnapshot.source=ba;
var jpegEncoder:JPEGEncoder = new JPEGEncoder(50);
var imageSnapshot:ImageSnapshot = ImageSnapshot.captureImage(this.myImageSnapshot,90,jpegEncoder);
var imageByteArray:ByteArray = imageSnapshot.data;
var newImage:File = File.desktopDirectory.resolvePath("KioskThumbs/"+filename+".jpg");
fileStream = new FileStream();
fileStream.open(newImage, FileMode.UPDATE);
fileStream.writeBytes(imageByteArray);
fileStream.close();
captured = true;
}
The above code really doesnt do anything special.
Its just using an image 'component' from flex, making it do the work for scaling the Video image, then taking the snapshot of this resized image component, and then writing it into a file.
My capture at last is:
private function capture(filename:String):void
{
var bitmapData:BitmapData = new BitmapData(videoDisplay.width, videoDisplay.height);
bitmapData.draw(videoDisplay,new Matrix());
var bitmap : Bitmap = new Bitmap(bitmapData);
var jpg:JPEGEncoder = new JPEGEncoder();
var ba:ByteArray = jpg.encode(bitmapData);
var newImage:File = File.desktopDirectory.resolvePath("KioskThumbs/"+filename+".jpg");
fileStream = new FileStream();
fileStream.open(newImage, FileMode.UPDATE);
fileStream.writeBytes(ba);
fileStream.close();
captured = true;
}
it works fine except the fact that i want to scale the photo lets say to 150 width 120height and not BitmapData(videoDisplay.width,videoDisplay.height); what can i do to solve that?
Thanks a lot all of you!

Resources