How to Store Persistent Data with the SharedObject Class (AS2)
People often want to create a “smart” skip intro button that allows a visitor to skip the intro on all future visits, as well as this one. Or perhaps a banner that remembers the visitor’s name. Maybe a local “high scores” listing for a game (just for the visitor, not a list of everyone’s high scores). For any of these goals, and countless more, your SWF will need the capacity to store persistent data; that is, data that stay on the user’s machine even after the browser has been closed. In traditional HTML development, this is often handled with JavaScript cookies. Flash has its own version of that, available since Flash Player 6, and it’s very easy to use. Let’s take a look.
An answer, short and sweet
This is sample code — more of a general approach than a “copy and paste this, exactly” snippet. Enter the following into a frame script:
var so:SharedObject = SharedObject.getLocal("testFlashCookie");
if (so.data.bitOfText) {
trace(so.data.bitOfText);
} else {
so.data.bitOfText = "data for next time";
so.flush();
}
How it works (and how to use it)
An arbitrarily named variable, so (short for SharedObject) is declared and set to the return value of the static SharedObject.getLocal() method. The parameter of this method, the string "testFlashCookie", refers to an arbitrarily named local shared object file (.sol extension) on the user’s computer. The getLocal() method is useful because it always returns a SharedObject instance (well, almost always; I’ll get to that in a moment). If the user has never been to this page before — and therefore doesn’t yet have the “testFlashCookie” file — the method creates it, on the spot, and returns a reference. On the other hand, if the user does have this local file, the method returns a reference to it. If, for some reason, the local file could not be created, the method returns null (this may be because the user has configured the Flash Player settings not to accept shared objects, much like some people choose to configure their browsers not to accept cookies).
An if statement checks the value of a special expression, so.data.bitOfText. If this expression is not undefined, then the property it references, bitOfText, clearly exists, so its value is traced to the Output panel. If the expression is undefined, the bitOfText property is set to a string, “data for next time,” and the SharedObject.flush() method immediately saves the shared object locally.
So what is this so.data.bitOfText expression? Well, all SharedObject instances have a data property. This property is an object that stores any of the countless custom properties you may wish to save in your “Flash cookie.” In the sample above, I’ve chosen a single string property by the arbitrary name bitOfText. For a “smart” skip intro scenario, you might want that property to be something like beenHereBefore, and it might be Boolean (true / false).
Let’s say, for example, your intro occurs between frames 1 and 100. A button is visible during these hundred frames that says “Skip intro” and another that says “Skip intro always.” The first button is easy to implement: simply have it send the main timeline to frame 101.
skipIntro.onRelease = function() {
this._parent.gotoAndPlay(101);
}
With me? The “Skip intro always” button is only marginally more difficult. Here’s how it might work:
var so:SharedObject = SharedObject.getLocal("myCoolSite");
skipIntroAlways.onRelease = function() {
so.data.beenHereBefore = true;
so.flush();
this._parent.gotoAndPlay(101);
}
First, a SharedObject instance is declared, as before. Remember, if there isn’t yet a “myCoolSite” file, it’ll be created for you. Next, a Button.onRelease event handler sets the so.data.beenHereBefore property to true, then sends the button’s parent timeline to frame 101.
To complete this scenario, you’d need a bit of code in frame 1, as well.
var so:SharedObject = SharedObject.getLocal("myCoolSite");
if (so.data.beenHereBefore == true) {
gotoAndPlay(101);
}
Makes sense, right? If the user is here for the very first time, this frame 1 code will create a “myCoolSite” file. Next, it’ll check to see if that file’s beenHereBefore property is set to true. The first time around, of course, the answer will be no. In fact, there won’t be a beenHereBefore property at all (so it certainly won’t be true). The expression so.data.beenHereBefore == true will evaluate to false, which means the gotoAndPlay() function will not be called; the user will see the intro.
The second, third, fourth, etc. visit, it will go the same way. When the user finally clicks the “Skip intro always” button, that property will finally have a value of true. The if statement in frame 1 will finally evaluate to true, and the intro will be skipped.
That’s one example of many. The cool part is, you can store whatever datatype you like in the SharedObject.data property: strings, numbers, objects, dates; even arrays and XML objects. Very, very handy. And remember, you can theoretically store as many custom properties as you like inside SharedObject.data. Just follow each in turn, one after the other. You’re only limited by the amount of hard drive space the user has chosen to allot for shared objects — but if you’re storing the occasional Boolean or handful of strings, you’re not likely to hit the limit.
July 31st, 2007 at 9:06 am
Sorry to be a pain but I don’t suppose you have a source file for this? I’m not a great action scripter and am a little confused on this one. Sorry to be a pain.
Many thanks
Shane
July 31st, 2007 at 8:59 pm
shane,
No worries, you’re not being a pain at all.
I actually don’t have the source file, but in order to make one, I’d simply copy/paste the code as shown in the above blog entry. Is that what you tried?