Posted by: Tushar | July 8, 2007

ActionScript 3: Serializing Classes using registerClassAlias

In previous article “Component and SharedObject Example” we’ve seen how to store simple variables in Local Shared Object. But, what if you want to store a custom class objects in Shared Object?

You can use flash.net. registerClassAlias() to do so. This method is similar to old Object.registerClass() (Removed in AS3).

Shared Objects are stored in AMF (Action Message Format) format. When you try to save class object in Shared Object, it will be stored as normal object. It will not have any reference to the class. Thus to save the information about the class, one has to use registerClassAlias class. This is also called as Serializing Classes.

Apart from SharedObject, this class can be used for LocalConnection, ByteArray , NetConnection and NetStream.

Here is a simple example of using registerClassAlias. In this example, object of Person class is stored in Shared Object. This example also demonstrates use of AS3 components (Label, ComboBox, Button, InputText).

AS3 Serializing example image

Below is the code:

Class Person:

package {
public class Person {
private var _name:String;
private var _age:uint;
private var _gender:String;
public function Person() {
this._name = "";
this._age = undefined;
this._gender = "";
}
public function get name():String {
return this._name;
}
public function set name(name:String):void {
this._name = name;
}
public function get age():uint {
return this._age;
}
public function set age(age:uint):void {
this._age = age;
}
public function get gender():String {
return this._gender;
}
public function set gender(gender:String):void {
this._gender = gender;
}
public function getPerson():String {
return "Name: " + this._name + " Age: " + this._age + " Gender: " + this._gender;
}
}
}

Class soExample:

package {
import fl.controls.Button;
import fl.controls.Label;
import fl.controls.TextInput;
import fl.controls.NumericStepper;
import fl.controls.ComboBox;
import fl.data.DataProvider;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.net.SharedObject;
import flash.net.registerClassAlias;
public class soExample extends Sprite {
private var getData_btn:Button;
private var setData_btn:Button;
private var delData_btn:Button;
private var titleLbl:Label;
private var statLbl:Label;
private var nameLbl:Label;
private var ageLbl:Label;
private var genderLbl:Label;
private var name_txt:TextInput;
private var ageNS:NumericStepper;
private var genderCB:ComboBox;
private var _mc:Sprite;
private var mySO:SharedObject;
private var tushar:Person;
public function soExample(_mc:Sprite) {
registerClassAlias(”PersonAlias”, Person);
this._mc = _mc;
updateUI();
updateDisplay();
getSO();
}
private function updateUI():void {
getData_btn = createButton("Get Shared Object", 150, 10, 160, "get_btn");
setData_btn = createButton("Store Shared Object", 150, 10, 190, "set_btn");
delData_btn = createButton("Delete Shared Object", 150, 10, 220, "del_btn");
titleLbl = createLabel("<b>AS3 - Shared Object Example</b>", 200, 10, 10);
statLbl = createLabel("", 400, 10, 250);
nameLbl = createLabel("Name: ", 100, 10, 50);
ageLbl = createLabel("Age: ", 100, 10, 80);
genderLbl = createLabel("Gender: ", 100, 10, 110);
name_txt = createTextInput(200, 60, 50);
ageNS = createNumericStepper(25, 50, 22, 60, 80);
genderCB = createComboBox(100, 22, 60, 110, new DataProvider(["Male", "Female"]));
}
private function updateDisplay():void {
_mc.addChild(titleLbl);
_mc.addChild(nameLbl);
_mc.addChild(ageLbl);
_mc.addChild(genderLbl);
_mc.addChild(statLbl);
_mc.addChild(getData_btn);
_mc.addChild(setData_btn);
_mc.addChild(delData_btn);
_mc.addChild(ageNS);
_mc.addChild(name_txt);
_mc.addChild(genderCB);
}
private function createButton(lbl:String, w:uint, x:uint, y:uint, nme:String):Button {
var BTN:Button = new Button();
BTN.label = lbl;
BTN.width = w;
BTN.move(x, y);
BTN.name = nme;
BTN.addEventListener(MouseEvent.CLICK, clickHandler);
return BTN;
}
private function createLabel(lbl:String, w:uint, x:uint, y:uint):Label {
var LBL:Label = new Label();
LBL.htmlText = lbl;
LBL.width = w;
LBL.move(x, y);
return LBL;
}
private function createTextInput(w:uint, x:uint, y:uint):TextInput {
var TI:TextInput = new TextInput();
TI.htmlText = "";
TI.width = w;
TI.move(x, y);
return TI;
}
private function createNumericStepper(defaultVal:uint, w:uint, h:uint, x:uint, y:uint):NumericStepper {
var NS:NumericStepper = new NumericStepper();
NS.move(x, y);
NS.setSize(w, h);
NS.minimum = 1;
NS.maximum = 150;
NS.stepSize = 1;
NS.value = defaultVal;
return NS;
}
private function createComboBox(w:uint, h:uint, x:uint, y:uint, _data:DataProvider):ComboBox {
var CB:ComboBox = new ComboBox();
CB.move(x, y);
CB.setSize(w, h);
CB.dataProvider = _data;
return CB;
}
private function clickHandler(event:MouseEvent):void {
respondToMouseEvent(event.target.name);
}
private function respondToMouseEvent(nme:String):void {
switch (nme) {
case "get_btn":
getSO();
break;
case "set_btn":
setSO();
break;
case "del_btn":
deleteSO();
break;
}
}
private function getSO():void {
name_txt.text = "";
mySO = SharedObject.getLocal(”person”);
if (mySO.size == 0) {
// Shared object doesn’t exist.
statLbl.htmlText = "Status: SharedObject not found.";
name_txt.text = "";
ageNS.value = 25;
genderCB.selectedIndex = 0;
} else {
name_txt.text = mySO.data.person.name;
ageNS.value = mySO.data.person.age;
if(mySO.data.person.gender == "Female"){
genderCB.selectedIndex = 1;
}
statLbl.htmlText = "Status: SharedObject value is - <b>"+mySO.data.person.getPerson()+"</b>";
}
}
private function setSO():void {
if (name_txt.text != "") {
tushar = createPerson(name_txt.text, ageNS.value, genderCB.selectedItem.data);
mySO.data.person = tushar;
mySO.flush();
getSO();
} else {
statLbl.htmlText = "Status: <b>Name</b> missing.";
}
}
private function deleteSO():void {
mySO.clear();
getSO();
}
private function createPerson(name:String, age:uint, gender:String):Person {
var tmpPerson = new Person();
tmpPerson.name = name;
tmpPerson.age = age;
tmpPerson.gender = gender;
return tmpPerson;
}
}
}

Now, create object of soExample and pass movieclip reference (in which all the components will be added at runtime) as parameter:

var mySoExample:soExample = new soExample(this);

Note: Be sure to add “Button”, “Label”, ”ComboBox”, ”NumericStepper” & “TextInput” components to the library of that movie.

Source:  AS3 Serializing Example (Zip file included)


Responses

  1. Nice blog!

  2. Thanks Debabrata!

  3. Thanks a lot! Really nice! I am gonna be coming back to this site!

  4. figured it out, had seperate main.as with:
    =============================
    package {
    import flash.display.Sprite;

    public class main extends Sprite {
    public function main():void {
    var mySoExample:soExample = new soExample(this);
    }
    }

    }
    ==========================
    as I’m sure you know :)

  5. Currently trying to modify the example by using a persistent server side object instead of a local one. Should SharedObject.data.(customClass) be used, or is there a better way?

  6. Hi, nice blog..

    can i ask you a question?

    i’ve created a custom value object class..a simple class with private properties and getters methods to retrieve them, like your person class.

    then i created an array collection where each item is a value object.
    then i have a shared object manager that looks like this:

    package util{

    import flash.net.SharedObject;

    import mx.collections.ArrayCollection;

    public class SharedObjectApplicationManager {

    private var mySO:SharedObject;
    private var ac:ArrayCollection;
    private var lsoType:String;

    public function SharedObjectApplicationManager(s:String) {
    init(s);
    }

    private function init(s:String):void {
    mySO = SharedObject.getLocal(s);
    if (getf()) {
    getf();
    }
    }

    public function getf():ArrayCollection {
    return mySO.data.arrayc;
    }

    private function adda(array:ArrayCollection):void {
    mySO.data.arrayc = new ArrayCollection();
    mySO.data.arrayc = array;
    mySO.flush();
    }
    }
    }

    so when i try to get arraycollection with getf method i get an arraycollection of generic objects…not with value objects..in this manner i can’t get value properties of value object class.

    so i would use registerClassAlias(“Info”, WindowInfo) where WindowInfo is the VO..but where?

    the architecture of my app is:

    -main application (verify the shared object, if full then call a public function of canvas to create windows with specific parameters saved in windowinfo class)
    –canvas (contains one or more windows)

    any suggestions?

    thanks in advance

    Regards Lorenzo

  7. tks a lot!!!
    i really need this, ’cause i’m doing the flash remoting things, and was stuck in the class mapping…

    thank you!

  8. is there away to serialize object contain object. For example, the Person Class has a private var info:Info. Info is a class has two string variables. I tried but it now working correctly. I was able to retrieve name, gender, and age fields but info only return null or 0. What is the problem?

  9. You can simply add [RemoteClass] or [RemoteClass("com.alias.Name")] class metatag:

    [RemoteClass]
    public class Person


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Categories

Follow

Get every new post delivered to your Inbox.