Objetos compartilhados

Flash Player 9 e posterior, Adobe AIR 1.0 e posterior

Um objeto compartilhado, às vezes referenciado como um “cookie Flash”. é um arquivo de dados que pode ser criado no computador pelos sites visitados. Objetos compartilhados são usados com maior frequência para aprimorar sua experiência de navegação na Web, por exemplo, permitindo personalizar a aparência de um site visitado com frequência.

Sobre os objetos compartilhados

Os objetos compartilhados funcionam como os cookies do navegador. Utilize a classe SharedObject para armazenar dados no disco rígido local do usuário e chamar dados durante a mesma sessão ou em uma sessão posterior. Os aplicativos podem acessar apenas seus próprios dados SharedObject, e somente quando executam no mesmo domínio. Os dados não foram enviados ao servidor e não estão acessíveis por outros aplicativos em execução nos outros domínios, mas podem tornar-se acessíveis por aplicativos do mesmo domínio.

Objetos compartilhados com cookies

Cookies e objetos compartilhados são muito similares. Como a maioria dos programadores da Web estão familiarizados com o modo como os cookies funcionam, pode ser útil fazer uma analogia entre os cookies e os SharedObjects locais.

Os cookies que aderem ao padrão RFC 2109 geralmente têm as seguintes propriedades:

  • Podem expirar e o fazem com frequência, por padrão, ao final da sessão.

  • Podem ser desativados pelo cliente em uma base específica por site.

  • Há um limite total de 300 cookies e 20 é o máximo por site.

  • Normalmente, estão limitados ao tamanho de 4 KB cada.

  • Algumas vezes, são percebidos como uma ameaça à segurança e, em resultado disso, ficam desativados no cliente.

  • São armazenados em um local especificado pelo navegador cliente.

  • São transmitidos do cliente ao servidor via HTTP.

    Por outro lado, os objetos compartilhados apresentam as seguintes propriedades:

  • Não expiram por padrão.

  • Por padrão, estão limitados ao tamanho de 100 KB cada.

  • Podem armazenar tipos de dados simples (como sequência de caracteres, matriz e data).

  • São armazenados em um local especificado pelo aplicativo (dentro do diretório base do usuário).

  • Nunca são transmitidos entre o cliente e o servidor.

Sobre a classe SharedObject

Utilize a classe SharedObject para criar e excluir objetos compartilhados e também, detectar o tamanho atual do objeto SharedObject que está sendo utilizado.

Criação de um objeto compartilhado

Para criar um objeto SharedObject utilize o método SharedObject.getLocal() , que possui a sintaxe a seguir:

SharedObject.getLocal("objectName" [, pathname]): SharedObject

O exemplo a seguir cria um objeto compartilhado denominado mySO:

public var mySO:SharedObject; 
mySO = SharedObject.getLocal("preferences");

Isso cria um arquivo na máquina do cliente denominado preferences.sol.

O termo local faz referência ao local do objeto compartilhado. Nesse caso, o Adobe® Flash® Player armazena o arquivo SharedObject localmente no diretório base do cliente.

Quando você cria um objeto compartilhado, o Flash Player cria um novo diretório para o aplicativo e o domínio dentro da sua caixa de proteção. Cria, também, um arquivo *.sol que armazena os dados do SharedObject. O local padrão desse arquivo é um subdiretório no diretório base do usuário. A tabela a seguir apresenta os locais padrão desse diretório:

Sistema operacional

Localização

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

Abaixo do diretório #SharedObjects, está um diretório nomeado randomicamente. Abaixo desse diretório, vem um diretório que corresponde ao nome do host, em seguida, o caminho para o aplicativo e, finalmente, o arquivo *.sol.

Por exemplo, se você solicitar um aplicativo denominado MyApp.swf no host local, dentro de um subdiretório denominado /sos, o Flash Player armazenará o arquivo *.sol no seguinte local (no Windows XP):

c:/Documents and Settings/fred/Application Data/Macromedia/Flash Player/#SharedObjects/KROKWXRK/#localhost/sos/MyApp.swf/data.sol
Nota: Se você não prover um nome no método SharedObject.getLocal() , o Flash Player nomeará o arquivo .sol indefinido.

Por padrão, o Flash pode salvar objetos SharedObject persistentes de até 100 KB por domínio. Esse valor pode ser configurado pelo usuário. Quando o aplicativo tenta salvar dados para um objeto compartilhado que ultrapassariam 100 KB, o Flash Player exibe a caixa de diálogo Armazenamento local, oferecendo a opção ao usuário de permitir ou negar o armazenamento local para o domínio que está solicitando o acesso.

Especificação de um arquivo

Você pode utilizar o parâmetro opcional pathname para especificar um local no arquivo SharedObject . Esse arquivo deve estar em um subdiretório do diretório SharedObject desse domínio. Por exemplo, se você solicitar um aplicativo no host local e especificar:

mySO = SharedObject.getLocal("myObjectFile","/");

O Flash Player gravará o arquivo SharedObject no diretório /#localhost (ou /localhost, se o aplicativo estiver offline). Isso será útil caso você deseje que mais de um aplicativo no cliente seja capaz de acessar o mesmo objeto compartilhado. Nesse caso, o cliente pode executar dois aplicativos Flex, que especifiquem um caminho para o objeto compartilhado que esteja na raiz do domínio, e acessar o mesmo objeto compartilhado em ambos os aplicativos. Para compartilhar dados entre mais de um aplicativo sem persistência, é possível usar o objeto LocalConnection.

Se você especificar um diretório não existente, o Flash Player não criará um arquivo SharedObject.

Adição de dados a um objeto compartilhado

Adicione dados a um arquivo SharedObject *.sol utilizando a propriedade data do objeto SharedObject. Para adicionar novos dados ao objeto compartilhado, use a seguinte sintaxe:

sharedObject_name.data.variable = value;

O exemplo a seguir inclui as propriedades userName , itemNumbers e adminPrivileges e seus valores, em um 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;

Depois de designar valores à propriedade data , instrua o Flash Player a gravá-los no arquivo do SharedObject. Para forçar o Flash Player a gravar os valores no arquivo SharedObject, use o método SharedObject . flush() , como segue:

mySO.flush();

Se você não chamar o método SharedObject.flush() , o Flash Player gravará os valores no arquivo quando o aplicativo for encerrado. No entanto, isso não concederá ao usuário a oportunidade de aumentar o espaço disponível que o Flash Player terá para armazenar os dados, caso estes excedam as configurações padrão. Assim, chamar SharedObject.flush() é uma boa pedida.

Ao usar o método flush() para gravar objetos compartilhados em uma unidade de disco rígido do usuário, verifique atentamente se o usuário desativou explicitamente o armazenamento local usando o Gerenciador de configurações do Flash Player ( www.macromedia.com/support/documentation/br/flashplayer/help/settings_manager07.html ), conforme mostrado no exemplo a seguir:

var so:SharedObject = SharedObject.getLocal("test"); 
trace("Current SharedObject size is " + so.size + " bytes."); 
so.flush();

Armazenamento de objetos em objetos compartilhados

Você pode armazenar objetos simples, como Matrizes ou Sequências de caracteres, em uma propriedade data do SharedObject.

O exemplo a seguir é uma classe ActionScript que define os métodos que controlam a interação com o objeto compartilhado. Estes métodos permitem que o usuário adicione e remova objetos do objeto compartilhado. Esta classe armazena uma ArrayCollection que contém objetos simples.

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(); 
        } 
    } 
 
}

O aplicativo Flex a seguir cria uma instância da classe ActionScript para cada um dos tipos de objetos compartilhados de que necessita. Em seguida, chama métodos nessa classe quando o usuário adiciona ou remove blogs ou URLs de sites.

<?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>

Armazenamento de objetos com tipo em objetos compartilhados.

É possível armazenar instâncias do ActionScript com tipo em objetos compartilhados. Isso é feito chamando o método flash.net.registerClassAlias() para registrar a classe. Se você criar uma instância da classe e armazená-la no membro de dados do objeto compartilhado e, posteriormente, ler o objeto, obterá uma instância com tipo. Por padrão, a propriedade objectEncoding do SharedObject tem suporte para a codificação AMF3 e extrai a instância armazenada do objeto SharedObject; a instância armazenada retém o mesmo tipo especificado quando você chamou o método registerClassAlias() .

(Somente iOS) Impede o backup em nuvem de objetos compartilhados locais

Você pode definir a propriedade SharedObject.preventBackup para controlar se os objetos compartilhados locais serão armazenados no serviço de backup em nuvem do iOS. Trata-se de uma exigência da Apple para conteúdos que possam ser restaurados ou novamente baixados, mas que constituem um requisito para o funcionamento adequado de seu aplicativo durante o uso offline.

Criação de vários objetos compartilhados

É possível criar vários objetos compartilhados para o mesmo aplicativo Flex. Para fazer isso, designe a cada um deles um nome da instância diferente, como no exemplo a seguir:

public var mySO:SharedObject = SharedObject.getLocal("preferences"); 
public var mySO2:SharedObject = SharedObject.getLocal("history");

Isso criará os arquivos preferences.sol e history.sol no diretório local do aplicativo Flex.

Criação de um SharedObject seguro

Ao criar um SharedObject remoto ou local usando getLocal() ou getRemote() , há um parâmetro opcional denominado secure que determina se o acesso a esse objeto compartilhado é restrito para arquivos SWF que são entregues por uma conexão HTTPS. Se esse parâmetro estiver definido como true e o arquivo SWF for entregue por HTTPS, o Flash Player criará um novo objeto compartilhado protegido ou obterá uma referência a um objeto compartilhado protegido existente. Esse objeto compartilhado protegido pode ser lido ou gravado apenas por arquivos SWF entregues por HTTPS que chamam SharedObject.getLocal() com o parâmetro secure definido como true . Se esse parâmetro estiver definido como false e o arquivo SWF for entregue por HTTPS, o Flash Player criará um novo objeto compartilhado ou obterá uma referência a um objeto compartilhado existente.

Esse objeto compartilhado pode ser lido ou gravado por arquivos SWF entregues por conexões não HTTPS. Se o arquivo SWF for entregue por uma conexão não HTTPS e você tentar definir esse parâmetro como true , haverá uma falha na criação de um novo objeto compartilhado (ou o acesso de um objeto compartilhado protegido criado anteriormente), um erro será emitido e o objeto compartilhado será definido como null . Se você tentar executar o seguinte snippet em uma conexão não HTTPS, o método SharedObject.getLocal() emitirá um erro:

try 
{ 
    var so:SharedObject = SharedObject.getLocal("contactManager", null, true); 
} 
catch (error:Error) 
{ 
    trace("Unable to create SharedObject."); 
}

Independentemente do valor desse parâmetro, os objetos compartilhados criados serão levados em consideração na contagem da quantidade total de espaço em disco permitida para um domínio.

Exibição de conteúdo de um objeto compartilhado

Os valores são armazenados em objetos compartilhados dentro da propriedade data . Você pode executar um loop em cada valor dentro de uma ocorrência do objeto compartilhado usando um loop for..in , conforme mostrado no exemplo a seguir:

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]); 
}

Destruição de objetos compartilhados

Para destruir um SharedObject no cliente, use o método SharedObject.clear() . Isso não destruirá os diretórios no caminho padrão dos objetos compartilhados do aplicativo.

O exemplo a seguir exclui o arquivo SharedObject do cliente:

public function destroySharedObject():void { 
    mySO.clear(); 
}

Exemplo de SharedObject

O exemplo a seguir demonstra que é possível armazenar objetos simples como, por exemplo, Date em um objeto SharedObject sem a necessidade de serializar e desserializar esses objetos.

Este exemplo inicia dando boas-vindas a você pela sua primeira visita. Assim que você clicar em Log Out, o aplicativo armazenará a data atual em um objeto compartilhado. Na próxima vez que iniciar o aplicativo ou atualizar a página, o aplicativo dará boas-vindas pelo seu retorno, com um lembrete sobre o tempo em que esteve desconectado.

Para ver o aplicativo em ação, inicie o aplicativo, clique em Log Out e atualize a página. O aplicativo exibirá a data e hora em que você clicou no botão Log Out na visita anterior. A qualquer momento, é possível excluir as informações armazenadas clicando no botão Excluir LSO.

<?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>