Previous Page
Next Page

Recipe 17.3. Saving a Local Shared Object

Problem

You want to save data in an LSO to the client computer.

Solution

Use the SharedObject.flush( ) method.

Discussion

Flash automatically attempts to save LSO data to disk when either the movie is unloaded from the Player (such as when the Player closes), when the SharedObject instance is garbage collected (which occurs when there are no longer any references to the instance) or when the SharedObject.clear( ) method is invoked. However, it isn't a good practice to rely on the automatic save function, as there are several reasons why the data might be written to disk successfully. Instead, you should explicitly instruct the LSO to write the data to disk using the SharedObject.flush( ) method:

var flushResult:String = example.flush(  );

The flush( ) method takes an optional parameter specifying the minimum amount of disk space, in bytes, that should be used when writing the shared object. The value specified defaults to 0, meaning that only the minimum required space should be used to write the local shared object to disk.

When the flush( ) method is invoked, it attempts to write the data to the client computer. The result of a flush( ) invocation can be one of three possibilities:

  • If the user denies LSO storage for the domain, or if the Flash Player fails to save the data for some reason, the data is not saved and the method throws an Error.

  • If the amount of disk space required to save the LSO's data is less than the local storage setting for the domain, the data is written to disk and the method returns SharedObjectFlushStatus.FLUSHED, indicating a successful call. When the optional minimum disk space is passed to flush( ), the amount of space allotted must be greater than or equal to that value for the data to be flushed successfully.

  • If the user has not allotted as much space as the shared object data requires, she is prompted to allow enough space or to deny access to save the data. When this happens, the method returns SharedObjectFlushStatus.PENDING. If the user chooses to grant access, the extra space is automatically allotted and the data is saved.

In the third case, in which the flush( ) method returns the SharedObjectFlushStatus.PENDING constant, there is an additional step you can take to determine whether the user grants or denies access to save the data. When the user makes a selection from the automatic prompt, the netStatus event is raised. It is up to you to define an event handler to handle the results in the way that is appropriate for your application. When the event handler is invoked, it is passed a parameter of type flash.events.NetStatusEvent. Examine the info.code string property to determine if the user granted access (when code is set to SharedObject.Flush.Success) or if the user denied access (when code is set to SharedObject.Flush.Failed).

Here is an example that invokes flush( ) to save the data explicitly. It then handles the possible responses:

var example:SharedObject = SharedObject.getLocal( "example" );
example.data.someData = "a value";
try {
  var flushResult:String = example.flush(  );
  // If the flush operation is pending, add an event handler for 
  // netStatus to determine if the user grants or denies access. 
  // Otherwise, just check the result. 
  if ( flushResult == SharedObjectFlushStatus.PENDING ) {
    // Add an event handler for netStatus so we can check if the user 
    // granted enough disk space to save the shared object. Invoke 
    // the onStatus method when the netStatus event is raised.
    example.addEventListener( NetStatusEvent.NET_STATUS, onStatus );

  } else if ( flushResult == SharedObjectFlushStatus.FLUSHED ) {
    // Saved successfully. Place any code here that you want to 
    // execute after the data was successfully saved.
  }
} catch ( e:Error ) {
  // This means the user has the local storage settings to 'Never.' 
  // If it is important to save your data, you may want to alert the 
  // user here. Also, if you want to make it easy for the user to change 
  // his settings, you can open the local storage tab of the Player 
  // Settings dialog box with the following code:
  // Security.showSettings( SecurityPanel.LOCAL_STORAGE );.
}
     
// Define the onStatus() function to handle the shared object's 
// status event that is raised after the user makes a selection from
// the prompt that occurs when flush(  ) returns "pending."
function onStatus( event:NetStatusEvent ):void {
  if ( event.info.code == "SharedObject.Flush.Success" ) {
    // If the event.info.code property is "SharedObject.Flush.Success", 
    // it means the user granted access. Place any code here that 
    // you want to execute when the user grants access.
  } else if ( event.info.code == "SharedObject.Flush.Failed" ) {
    // If the event.info.code property is "SharedObject.Flush.Failed", it 
    // means the user denied access. Place any code here that you 
    // want to execute when the user denies access.
  }
  
  // Remove the event listener now since we only needed to listen once
  example.removeEventListener( NetStatusEvent.NET_STATUS, onStatus );
};

If you know in advance that a shared object is likely to continue to increase in size with each session, it is prudent to request a larger amount of local storage space when the shared object is created. Otherwise, each time the current allotted space is exceeded, the user is prompted again to accept or deny the storage request. Setting aside extra space avoids repeatedly asking the user for permission to store incrementally more data. In this situation, the minimum disk space parameter should be passed to the flush( ) method to specify a certain number of bytes to set aside for the shared object:

// Request 500 KB of space for the shared object.
var flashResult:String = example.flush( 500 * 1024 );

See Also

Recipe 17.8


Previous Page
Next Page
Converted from CHM to HTML with chm2web Pro 2.85 (unicode)