Shared objects
Flash Player 9 and later, Adobe AIR 1.0 and
later
A
shared object, sometimes referred to as a “Flash cookie,” is a data
file that can be created on your computer by the sites that you
visit. Shared objects are most often used to enhance your web-browsing
experience—for example, by allowing you to personalize the look
and feel of a website that you frequently visit.
About shared objects
Shared objects
function like browser cookies. You use the
SharedObject
class to store data on
the user’s local hard disk and call that data during the same session or
in a later session. Applications can access only their own SharedObject
data, and only if they are running on the same domain. The data
is not sent to the server and is not accessible by other applications
running on other domains, but can be made accessible by applications
from the same domain.
Shared objects compared with cookies
Cookies
and shared objects are very similar. Because most web programmers
are familiar with how cookies work, it might be useful to compare
cookies and local SharedObjects.
Cookies that adhere to the RFC 2109 standard generally have the
following properties:
-
They can expire, and often do at the end of a session
by default.
-
They can be disabled by the client on a site-specific basis.
-
There is a limit of 300 cookies total, and 20 cookies maximum
per site.
-
They are usually limited to a size of 4 KB each.
-
They are sometimes perceived to be a security threat, and
as a result, they are sometimes disabled on the client.
-
They are stored in a location specified by the client browser.
-
They are transmitted from client to server through HTTP.
In
contrast, shared objects have the following properties:
-
They do not expire by default.
-
By default, they are limited to a size of 100 KB each.
-
They can store simple data types (such as String, Array,
and Date).
-
They are stored in a location specified by the application
(within the user’s home directory).
-
They are never transmitted between the client and server.
About the SharedObject class
Using the
SharedObject
class, you can create
and delete shared objects, as well as detect the current size of
a SharedObject object that you are using.
Creating a shared object
To create a
SharedObject
object, use the
SharedObject.getLocal()
method,
which has the following syntax:
SharedObject.getLocal("objectName" [, pathname]): SharedObject
The following example creates a shared object called mySO:
public var mySO:SharedObject;
mySO = SharedObject.getLocal("preferences");
This creates a file on the client’s machine called preferences.sol.
The term
local
refers to the location of the shared object.
In this case, Adobe® Flash® Player
stores the SharedObject file locally in the client’s home directory.
When you create a shared object, Flash Player creates a new directory
for the application and domain inside its sandbox. It also creates
a *.sol file that stores the SharedObject data. The default location
of this file is a subdirectory of the user’s home directory. The
following table shows the default locations of this directory:
Operating System
|
Location
|
Windows 95/98/ME/2000/XP
|
c:/Documents and Settings/username/Application Data/Macromedia/Flash Player/#SharedObjects
|
Windows Vista/Windows 7
|
c:/Users/username/AppData/Roaming/Macromedia/Flash Player/#SharedObjects
|
Macintosh OS X
|
/Users/username/Library/Preferences/Macromedia/Flash Player/#SharedObjects/web_domain/path_to_application/application_name/object_name.sol
|
Linux/Unix
|
/home/username/.macromedia/Flash_Player/#SharedObjects/web_domain/path_to_application/application_name/object_name.sol
|
Below the #SharedObjects directory is a randomly-named directory.
Below that is a directory that matches the hostname, then the path
to the application, and finally the *.sol file.
For example, if you request an application named MyApp.swf on
the local host, and within a subdirectory named /sos, Flash Player
stores the *.sol file in the following location on Windows XP:
c:/Documents and Settings/fred/Application Data/Macromedia/Flash Player/#SharedObjects/KROKWXRK/#localhost/sos/MyApp.swf/data.sol
Note:
If you do not provide a name in the
SharedObject.getLocal()
method,
Flash Player names the file undefined.sol.
By default, Flash can save locally persistent SharedObject objects
of up to 100 KB per domain. This value is user-configurable. When
the application tries to save data to a shared object that would
make it bigger than 100 KB, Flash Player displays the Local Storage
dialog box, which lets the user allow or deny more local storage
for the domain that is requesting access.
Specifying a path
You can use the optional
pathname
parameter to specify
a location for the
SharedObject
file. This file must
be a subdirectory of that domain’s SharedObject directory. For example,
if you request an application on the localhost and specify the following:
mySO = SharedObject.getLocal("myObjectFile","/");
Flash Player writes the SharedObject file in the /#localhost
directory (or /localhost if the application is offline). This is
useful if you want more than one application on the client to be
able to access the same shared object. In this case, the client
could run two Flex applications, both of which specify a path to
the shared object that is the root of the domain; the client could
then access the same shared object from both applications. To share
data between more than application without persistence, you can
use the LocalConnection object.
If you specify a directory that does not exist, Flash Player
does not create a SharedObject file.
Adding data to a shared object
You add data to a
SharedObject
’s *.sol file using the
data
property
of the SharedObject object. To add new data to the shared object,
use the following syntax:
sharedObject_name.data.variable = value;
The following example adds the
userName
,
itemNumbers
,
and
adminPrivileges
properties and their values
to a SharedObject:
public var currentUserName:String = "Reiner";
public var itemsArray:Array = new Array(101,346,483);
public var currentUserIsAdmin:Boolean = true;
mySO.data.userName = currentUserName;
mySO.data.itemNumbers = itemsArray;
mySO.data.adminPrivileges = currentUserIsAdmin;
After you assign values to the
data
property,
you must instruct Flash Player to write those values to the SharedObject’s
file. To force Flash Player to write the values to the SharedObject’s
file, use the
SharedObject
.
flush()
method,
as follows:
mySO.flush();
If you do not call the
SharedObject.flush()
method,
Flash Player writes the values to the file when the application
quits. However, this does not provide the user with an opportunity
to increase the available space that Flash Player has to store the
data if that data exceeds the default settings. Therefore, it is
a good practice to call
SharedObject.flush()
.
When using the
flush()
method to write shared
objects to a user’s hard drive, you should be careful to check whether
the user has explicitly disabled local storage using the Flash Player
Settings Manager (
www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager07.html
),
as shown in the following example:
var so:SharedObject = SharedObject.getLocal("test");
trace("Current SharedObject size is " + so.size + " bytes.");
so.flush();
Storing objects in shared objects
You
can store simple objects such as Arrays or Strings in a SharedObject’s
data
property.
The
following example is an ActionScript class that defines methods
that control the interaction with the shared object. These methods
let the user add and remove objects from the shared object. This
class stores an ArrayCollection that contains simple objects.
package {
import mx.collections.ArrayCollection;
import flash.net.SharedObject;
public class LSOHandler {
private var mySO:SharedObject;
private var ac:ArrayCollection;
private var lsoType:String;
// The parameter is "feeds" or "sites".
public function LSOHandler(s:String) {
init(s);
}
private function init(s:String):void {
ac = new ArrayCollection();
lsoType = s;
mySO = SharedObject.getLocal(lsoType);
if (getObjects()) {
ac = getObjects();
}
}
public function getObjects():ArrayCollection {
return mySO.data[lsoType];
}
public function addObject(o:Object):void {
ac.addItem(o);
updateSharedObjects();
}
private function updateSharedObjects():void {
mySO.data[lsoType] = ac;
mySO.flush();
}
}
}
The following Flex application creates an instance
of the ActionScript class for each of the types of shared objects
it needs. It then calls methods on that class when the user adds
or removes blogs or site URLs.
<?xml version="1.0"?>
<!-- lsos/BlogAggregator.mxml -->
<mx:Application
xmlns:local="*"
xmlns:mx="http://www.adobe.com/2006/mxml"
creationComplete="initApp()"
backgroundColor="#ffffff"
>
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.utils.ObjectUtil;
import flash.net.SharedObject;
[Bindable]
public var welcomeMessage:String;
[Bindable]
public var localFeeds:ArrayCollection = new ArrayCollection();
[Bindable]
public var localSites:ArrayCollection = new ArrayCollection();
public var lsofeeds:LSOHandler;
public var lsosites:LSOHandler;
private function initApp():void {
lsofeeds = new LSOHandler("feeds");
lsosites = new LSOHandler("sites");
if (lsofeeds.getObjects()) {
localFeeds = lsofeeds.getObjects();
}
if (lsosites.getObjects()) {
localSites = lsosites.getObjects();
}
}
// Adds a new feed to the feeds DataGrid.
private function addFeed():void {
// Construct an object you want to store in the
// LSO. This object can contain any number of fields.
var o:Object = {name:ti1.text, url:ti2.text, date:new Date()};
lsofeeds.addObject(o);
// Because the DataGrid's dataProvider property is
// bound to the ArrayCollection, Flex updates the
// DataGrid when you call this method.
localFeeds = lsofeeds.getObjects();
// Clear the text fields.
ti1.text = '';
ti2.text = '';
}
// Removes feeds from the feeds DataGrid.
private function removeFeed():void {
// Use a method of ArrayCollection to remove a feed.
// Because the DataGrid's dataProvider property is
// bound to the ArrayCollection, Flex updates the
// DataGrid when you call this method. You do not need
// to update it manually.
if (myFeedsGrid.selectedIndex > -1) {
localFeeds.removeItemAt(myFeedsGrid.selectedIndex);
}
}
private function addSite():void {
var o:Object = {name:ti3.text, date:new Date()};
lsosites.addObject(o);
localSites = lsosites.getObjects();
ti3.text = '';
}
private function removeSite():void {
if (mySitesGrid.selectedIndex > -1) {
localSites.removeItemAt(mySitesGrid.selectedIndex);
}
}
]]>
</mx:Script>
<mx:Label text="Blog aggregator" fontSize="28"/>
<mx:Panel title="Blogs">
<mx:Form id="blogForm">
<mx:HBox>
<mx:FormItem label="Name:">
<mx:TextInput id="ti1" width="100"/>
</mx:FormItem>
<mx:FormItem label="Location:">
<mx:TextInput id="ti2" width="300"/>
</mx:FormItem>
<mx:Button id="b1" label="Add Feed" click="addFeed()"/>
</mx:HBox>
<mx:FormItem label="Existing Feeds:">
<mx:DataGrid
id="myFeedsGrid"
dataProvider="{localFeeds}"
width="400"
/>
</mx:FormItem>
<mx:Button id="b2" label="Remove Feed" click="removeFeed()"/>
</mx:Form>
</mx:Panel>
<mx:Panel title="Sites">
<mx:Form id="siteForm">
<mx:HBox>
<mx:FormItem label="Site:">
<mx:TextInput id="ti3" width="400"/>
</mx:FormItem>
<mx:Button id="b3" label="Add Site" click="addSite()"/>
</mx:HBox>
<mx:FormItem label="Existing Sites:">
<mx:DataGrid
id="mySitesGrid"
dataProvider="{localSites}"
width="400"
/>
</mx:FormItem>
<mx:Button id="b4" label="Remove Site" click="removeSite()"/>
</mx:Form>
</mx:Panel>
</mx:Application>
Storing typed objects in shared objects
You
can store typed ActionScript instances in shared objects. You do
this by calling the
flash.net.registerClassAlias()
method
to register the class. If you create an instance of your class and
store it in the data member of your shared object and later read
the object out, you will get a typed instance. By default, the SharedObject
objectEncoding
property
supports AMF3 encoding, and unpacks your stored instance from the
SharedObject object; the stored instance retains the same type you
specified when you called the
registerClassAlias()
method.
(iOS only) Prevent cloud backup of local shared objects
You can set the
SharedObject.preventBackup
property
to control whether local shared objects will be backed up on the
iOS cloud backup service. This is required by Apple for content
that can be regenerated or downloaded again, but that is required
for proper functioning of your application during offline use.
Creating multiple shared objects
You can create multiple shared objects for the same Flex
application. To do this, you assign each of them a different instance
name, as the following example shows:
public var mySO:SharedObject = SharedObject.getLocal("preferences");
public var mySO2:SharedObject = SharedObject.getLocal("history");
This creates a preferences.sol file and a history.sol file in
the Flex application’s local directory.
Creating a secure SharedObject
When
you create either a local or remote SharedObject using
getLocal()
or
getRemote()
,
there is an optional parameter named
secure
that
determines whether access to this shared object is restricted to
SWF files that are delivered over an HTTPS connection. If this parameter
is set to
true
and your SWF file is delivered over
HTTPS, Flash Player creates a new secure shared object or gets a reference
to an existing secure shared object. This secure shared object can
be read from or written to only by SWF files delivered over HTTPS
that call
SharedObject.getLocal()
with the secure
parameter set to
true
. If this parameter is set
to
false
and your SWF file is delivered over HTTPS,
Flash Player creates a new shared object or gets a reference to
an existing shared object.
This shared object can be read from or written to by SWF files
delivered over non-HTTPS connections. If your SWF file is delivered
over a non-HTTPS connection and you try to set this parameter to
true
,
the creation of a new shared object (or the access of a previously
created secure shared object) fails, an error is thrown, and the
shared object is set to
null
. If you attempt to
run the following snippet from a non-HTTPS connection, the
SharedObject.getLocal()
method will
throw an error:
try
{
var so:SharedObject = SharedObject.getLocal("contactManager", null, true);
}
catch (error:Error)
{
trace("Unable to create SharedObject.");
}
Regardless of the value of this parameter, the created shared
objects count toward the total amount of disk space allowed for
a domain.
Displaying contents of a shared object
Values
are stored in shared objects within the
data
property.
You can loop over each value within a shared object instance by
using a
for..in
loop, as the following example
shows:
var so:SharedObject = SharedObject.getLocal("test");
so.data.hello = "world";
so.data.foo = "bar";
so.data.timezone = new Date().timezoneOffset;
for (var i:String in so.data)
{
trace(i + ":\t" + so.data[i]);
}
Destroying shared objects
To destroy a
SharedObject
on the client,
use the
SharedObject.clear()
method. This does
not destroy directories in the default path for the application’s shared
objects.
The following example deletes the SharedObject file from the
client:
public function destroySharedObject():void {
mySO.clear();
}
SharedObject example
The following example shows that you can store simple objects,
such as a Date object, in a
SharedObject
object without having
to manually serialize and deserialize those objects.
The following example begins by welcoming you as a first-time
visitor. When you click Log Out, the application stores the current
date in a shared object. The next time you launch this application
or refresh the page, the application welcomes you back with a reminder
of the time you logged out.
To see the application in action, launch the application, click
Log Out, and then refresh the page. The application displays the
date and time that you clicked the Log Out button on your previous
visit. At any time, you can delete the stored information by clicking
the Delete LSO button.
<?xml version="1.0"?>
<!-- lsos/WelcomeMessage.mxml -->
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" initialize="initApp()">
<mx:Script><![CDATA[
public var mySO:SharedObject;
[Bindable]
public var welcomeMessage:String;
public function initApp():void {
mySO = SharedObject.getLocal("mydata");
if (mySO.data.visitDate==null) {
welcomeMessage = "Hello first-timer!"
} else {
welcomeMessage = "Welcome back. You last visited on " +
getVisitDate();
}
}
private function getVisitDate():Date {
return mySO.data.visitDate;
}
private function storeDate():void {
mySO.data.visitDate = new Date();
mySO.flush();
}
private function deleteLSO():void {
// Deletes the SharedObject from the client machine.
// Next time they log in, they will be a 'first-timer'.
mySO.clear();
}
]]></mx:Script>
<mx:Label id="label1" text="{welcomeMessage}"/>
<mx:Button label="Log Out" click="storeDate()"/>
<mx:Button label="Delete LSO" click="deleteLSO()"/>
</mx:Application>
|
|
|
|
|