As3 for iOS:How to Serialize an Array and Then Save It

AS3 for ios : how to serialize an array and then save it

You need to use flash.net.registerClassAlias.

So if I had a class like this:

package com {
public class Bob {
public var myArray:Array;
}
}

I could do this:

registerClassAlias("com.Bob", Bob);

Then you can save Bob class objects into your shared objects (or rather retrieve them again)

Full example:

//register the class - you only need to do this once in your class
registerClassAlias("com.Bob", Bob);

//Lets save a Bob instance into a shared object
var bob:Bob = new Bob();
bob.myArray = ["blah","blah","blah"];

var bobSO:SharedObject = SharedObject.getLocal("Bob");
bobSO.data.bob = new Bob();
bobSO.flush();

//now at a later time, let's retrieve it
var bobInstance:Bob;
var bobSO:SharedObject = SharedObject.getLocal("Bob");
if (bobSO.size > 0 && bobSO.data.bob && bobSO.data.bob != undefined) {
bobInstance = bobSO.data.bob;
}

Keep in mind, that you'll need to register ALL classes that are used (if you have different classes stored in your array).

AS3 Custom Object to ByteArray then to Custom Object

What you want to do is use the registerClassAlias method to register type information along with the data. That way Flash will know how to serialize/deserialize your object. Here's some sample code from Adobe's documentation:

registerClassAlias("com.example.eg", ExampleClass);
var eg1:ExampleClass = new ExampleClass();
var ba:ByteArray = new ByteArray();
ba.writeObject(eg1);
ba.position = 0;
var eg2:* = ba.readObject();
trace(eg2 is ExampleClass); // true

It should be noted that all types that should be serialized must be registered for the type information to be saved. So if you have another type that is referenced by your type, it too must be registered.

loading saved bitmap

To store a bitmap in a shared object, you would need to serialize it to a byte array first (see Is it possible to store images in the SharedObject of Flash?)

What you can do, is just store your custom BitmapData subclass in the shared object (if you don't want to bother with byte arrays)

//you need to register every class/subclass in your shared object
registerClassAlias("flash.display.BitmapData", BitmapData);

var saveDataTxt:SharedObject = SharedObject.getLocal("File");

var textName:String; var textClass:Class;

textName = "Text0" + 1; textClass = getDefinitionByName(textName) as Class;
registerClassAlias(textName,textClass); //need to register the custom class

var tx:BitmapData = new textClass(); txtP[1] = new Bitmap(tx);

saveDataTxt.data.txtArray[1] = tx; //just store the bitmap data

addChild(new Bitmap(saveDataTxt.data.txtArray[n] as BitmapData)); //you have to cast the object as bitmap data

Objects saved in a shared object are not keeping their data type after restart. Any ideas?

AS3 lang ref about SharedObject data:

Each attribute can be an object of any ActionScript or JavaScript type — Array, Number, Boolean, ByteArray, XML, and so on. For example, the following lines assign values to various aspects of a shared object:

Try to use ByteArray. How write object in SO:

            var list:ArrayList = new ArrayList(["test"]);
var buffer:ByteArray = new ByteArray();
buffer.writeObject(list);
buffer.position = 0;

var mySo:SharedObject = SharedObject.getLocal("application");
mySo.data.list = buffer;
mySo.flush();

And read object:

            var mySo:SharedObject = SharedObject.getLocal("application");
var buffer:ByteArray = mySo.data.list;
var result:ArrayList = ArrayList( buffer.readObject() );

For custom class, use registerClassAlias, see Vesper comment.

Red5 throws Error loading class when using a custom class as a SharedObject

I've solved the problem, but I'm no Red5 expert so take the following explanation with a grain of salt and correct me if I'm wrong... It seems that either Red5, or the "live" application included with Red5, attempts to instantiate whatever objects it receives via a SharedObject on the server-side. So, I believe you would actually need to replicate in Java whatever CustomClasses you're sharing from the client-side in AS3. Seems really odd to me, but that's all I can gather, and that would explain the Red5 error logs.

This was unacceptable for my needs, as I plan to have other programmers take my client-side code as an API and abstract away the server-side details... so recreating whatever classes they come up with on the server isn't really feasible.

An easy workaround is to "wrap" whatever you're sharing in a ByteArray and then unwrap it when you retrieve it. Red5 doesn't seem to complain about ByteArrays, and happily broadcasts them out to the client with no knowledge of what's inside. Here are a couple functions I whipped up to handle this...

    private function setRed5Property(propertyName:String, data:Object):void
{
var dataBytes:ByteArray = new ByteArray();
dataBytes.writeObject(data);

_red5SharedObject.setProperty(propertyName, dataBytes);
_red5SharedObject.setDirty(propertyName);
}

private function getRed5Property(propertyName:String):Object
{
var dataBytes:ByteArray = new ByteArray();
dataBytes.writeBytes(_red5SharedObject.data[propertyName]);
dataBytes.position = 0;

return dataBytes.readObject() as Object;
}

Kiosk game writing local files AS3 without AIR? Possible? If not, local server?

If you are dealing only with small data, SharedObjects can solve your problem just as LondonDrugs_MediaServices said in his comment. You can write anything to those, but its limited to 100KB by default. To get more you must accept a prompt or preset it to a bigger size.

Is there any way to write to local files without a prompt?

SharedObjects aside, you cannot do that for security reasons. If you are using only the flash player, web or projector, you cannot write files directly without a prompt. You can read local files from both but you must know your sandbox as it gets messy when you mix network and local file access.

If you can run a local webserver I suggest you use Mongoose because it is small,has PHP, is simple to setup and can run on mostly anything. Beware that you still have to mind your security sandbox, but serving your SWF from the same local webserver simplifies that.

Converting an image promise to byteArray AS3

The **Media**Promise - handling differs a little on iOS from e.g. Android.
(Unfortunately you didn't state, which platform you are targeting)

In the most simple case, it will return you a File in mediaPromise.file Property. You can load this either by using Loader or FileStream, whichever you like most.

Listen to the MediaEvent. When it fires, you get either a file or you will have to load the mediaPromise first using Loader

Try this: (code is not error checked nor complete but should give you an idea:

private function onPictureTaken(e:MediaEvent):void
{
// first we have to find out, if file is already saved (as on Android or BB TabletOS )
// or has to be loaded first (like on iOS)
var mediaPromise:MediaPromise = e.data;

if(mediaPromise.file == null) // is iOS
{
trace("iOS Device found");
// it would be a good idea to give the anonymous bitmap a name:
var date:String = DateUtils.dateToString( new Date ,"yyyy-MM-dd_HH-mm-ss");
_fileName = "Image_" +date + "." + saveMode; // add right extension

_loader = new Loader();
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onIOSImageLoadComplete);
_loader.loadFilePromise(mediaPromise);

}
else // anything else
{
trace("non-iOS Device found");

file = mediaPromise.file;
_fileName = mediaPromise.file.name;
// you can directly access files bytes here:
var fs:FileStream = new FileStream;
var bytes:ByteArray = new ByteArray;
fs.open(file , FileMode.READ);
fs.readBytes(bytes);
fs.close();
// you now have your byteArray

}
}
private function onIOSImageLoadComplete(e:Event):void
{
// iOS handles over pictures as Bitmap, so it should to be rencoded to jpeg or png prior to uploading
// take a look at JPEGEncoder, for example.
// it will return a byteArray also, which you can use to upload;
var bmp:Bitmap = _loader.content as Bitmap;
var bytes:ByteArray = new JPEGEncoder(50).encode(bmp.bitmapData);
}


Related Topics



Leave a reply



Submit