DevSecOps

24 jun, 2009

Usando shared objects

Publicidade

Salve, pessoal.

Neste artigo irei demonstrar uma funcionalidade muito utilizada em
sites, que é o armazenamento de dados no cookie do browser. Esta
função é muito utilizada para salvar as preferências de usuários, como
login, email, último acesso entre outras informações. No Flex isso também é possível, podendo ser até mais poderoso do que as
formas atuais. Para fazer isso, você deve utilizar o SharedObject.

A função do Shared Objects (ShO) é armazenar um montante de dados no
computador do cliente, funcionando como um cookies do browser. Assim,
você pode armazenar dados e chamá-los durante a sessão atual ou em
outra futura sessão. Contudo estes dados não podem ser acessados por
outra aplicação Flex, mas sim apenas pela aplicação criadora.

Shared Objects vs Cookies

É comum desenvolvedores confundirem ShO com cookies, já que a maioria trabalham ou já trabalharam com cookies.

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

  • Eles podem expirar e, geralmente, isso é feito no final da sessão, por default.
  • Podem ser desabilitados pelos clientes.
  • Há um limite de 300 cookies, sendo no máximo 20 por site.
  • Um cookie tem o espaço de armazenamento de 4 kb.
  • Há a possibilidade de serem considerados como arquivos maliciosos.
  • Há uma comunicação entre cliente e servidor para armazenamento dos dados.

Já o Shared Object tem as seguintes características:

  • Eles não expiram por default.
  • Por padrão, o seu limite de armazenamento é de 100 kb.
  • Eles podem armazenar dados simples como: String, Date, Array .
  • A aplicação pode indicar locais específicos para o armazenamento dos dados.
  • Não há transmissão e comunicação entre o cliente e o servidor para a busca e armazenamento dos dados.

Assim, com este pequeno resumo é possível ver claramente as diferenças entre Cookies e ShO, sendo visível o total poder do ShO.

Certo. Agora que já vimos resumidamente do que o Shared Objects é capaz,
vamos então nos aprofundar na classe SharedObject visualizando, assim,
seu funcionamento e o que mais ele é capaz.

SharedObject.class

Com esta classe você é capaz de realizar qualquer manipulação dos
dados que ficarão armazenados no cliente. Esta possui os seguintes
métodos:

  • clear() Limpa permanentemente todos os dados contidos no Shared Object.
  • flush() Grava os dados do ShO no cliente.
  • getLocal() Retorna uma instância do ShO no cliente, caso não exista o mesmo cria uma.
  • getSize()
    Retorna o tamanho em Bytes do ShO no cliente. Uma observação o
    tamanho default é de 100kb, contudo isto pode ser alterado para mais.

Pronto, estes são todos os métodos que você deve saber para manipular os ShO’s. Agora vamos para à melhor parte: a mão na massa.

Criando uma lista de contatos

Para exemplificar este artigo, irei criar um Painel onde poderá
ser adicionada uma lista de contatos. Assim, depois de adicionada, você
poderá recarregar o swf e a lista ainda continuará na tela.

Passo 1:

Criar uma classe chamada ShareObjectHelper, que irá realizar a
manipulação dos dados do Shared Object, tais como: incluir, remover e
listar.  Esta é uma classe bem simples utilizaremos um ArrayCollection para
armazenar todos os dados que armazenarão dos contatos que o usuário
incluiu.

package {
import mx.collections.ArrayCollection;
import flash.net.SharedObject;
 
/**
* @author Fabiel Prestes
*/
public class SharedObjectHelper {
 
private var _sharedObject:SharedObject;
private var _dadosSharedObject:ArrayCollection;
private var _nomeArquivoSharedObject:String;
 
/**
* Construtor
*/
public function SharedObjectHelper(valor:String) {
inicializaHelper(valor);
}
 
/**
* @private
* Responsavel por recuperar a instancia do SharedObject baseado no
* parametro.
*
*/
private function inicializaHelper(valor:String):void {
_dadosSharedObject = new ArrayCollection();
_nomeArquivoSharedObject = valor;
_sharedObject = SharedObject.getLocal(_nomeArquivoSharedObject);
 
if (getObjects()) {
_dadosSharedObject = getObjects();
}
}
 
/**
* Retorna todos um array de dados que está armazendo no SharedObject
* @return ArrayCollection
*/
public function getObjects():ArrayCollection {
return _sharedObject.data[_nomeArquivoSharedObject];
}
 
/**
* Adiciona um dado ao array de dados.
* @param Object
*/
public function addObject(o:Object):void {
_dadosSharedObject.addItem(o);
updateSharedObjects();
}
 
/**
* @private
* Vincula o array de dados a um SharedObject.
*/
private function updateSharedObjects():void {
_sharedObject.data[_nomeArquivoSharedObject] = _dadosSharedObject;
_sharedObject.flush();
}
}
 
}

Com a nossa classe que irá realizar todas as operações no objeto
ShareObject pronta, vamos criar a classe de teste, que basicamente a
interface é um Panel com um Form.

Nesta classe, o que temos de prestar atenção é nos únicos 3 métodos:

  1. initApp() Este método é chamado quando a
    aplicação acabou de ser criada, neste momento é criado um objeto
    SharedObjectHelper para este recurpar uma instancia de SharedObject.
  2. addContato()
    Responsável por pegar os dados cadastrados no formulário e inserir na
    dataGrid e também de criar um objeto dinâmico com os dados do
    formulário e executar o método da classe SharedObjectHelper tratar o
    objeto criado.
  3. removerContato() Remove um contato selecionado do dataGrid e também da lista de contatos que existe no SharedObject.

Essas são todas as funcionalidades da classe teste, sendo assim basta criar a seguinte classe SharedObjectTeste.

	<?xml version="1.0"?>
 
<mx:Application xmlns:local="*" xmlns:mx="http://www.adobe.com/2006/mxml"
creationComplete="initApp()" backgroundColor="#ffffff"
layout="vertical"
backgroundGradientAlphas="[1.0, 1.0]"
backgroundGradientColors="[#A5C3D5, #A5C3D5]">
<mx:Script>
<![CDATA[
import mx.events.ValidationResultEvent;
import mx.validators.ValidationResult;
import mx.collections.ArrayCollection;
import mx.utils.ObjectUtil;
import flash.net.SharedObject;
 
[Bindable]
public var listaContatos:ArrayCollection = new ArrayCollection();
 
public var shoHelper:SharedObjectHelper;
 
/**
* @private
* Inicializa a classe SharedObjectHelper e ja cria/recupera
* instancia de um objeto SharedObject.
*/
private function initApp():void {
shoHelper = new SharedObjectHelper("contatosSalvos");
 
if (shoHelper.getObjects()) {
listaContatos = shoHelper.getObjects();
}
 
}
 
/**
* @private
* Adiciona um contato na lista de contatos e executa o addObject da classe
* sharedObjectHelper.
*/
private function addContato():void {
if(valNome.validate().type == ValidationResultEvent.VALID){
/* Cria um objeto dinamico com os atributos dos fomularios */
var objTemp:Object = {nome: tiNome.text, sobrenome: tiSobrenome.text, fone:tiFone.text};
shoHelper.addObject(objTemp);
 
listaContatos = shoHelper.getObjects();
 
/* Limpa os campos do formularios */
tiNome.text = '';
tiSobrenome.text = '';
tiFone.text = '';
}
}
 
/**
* @private
* Remove um contato do DataGrid e da lista de contatos do SharedObejct
*/
public function removerContato():void {
if (dgContatos.selectedIndex > -1) {
listaContatos.removeItemAt(dgContatos.selectedIndex);
}
}
 
]]>
</mx:Script>
<mx:StringValidator id="valNome" source="{tiNome}" property="text"
required="true" requiredFieldError="Preencher Campo"
triggerEvent="''"/>
 
<mx:Panel title="Contatos" layout="vertical" horizontalAlign="center" width="70%">
<mx:Form width="100%">
<mx:FormItem label="Nome" width="100%">
<mx:TextInput id="tiNome" width="100%"/>
</mx:FormItem>
<mx:FormItem label="Sobrenome" width="100%">
<mx:TextInput id="tiSobrenome" width="100%"/>
</mx:FormItem>
<mx:FormItem label="fone">
<mx:TextInput id="tiFone"/>
</mx:FormItem>
</mx:Form>
 
<mx:DataGrid id="dgContatos" dataProvider="{listaContatos}" width="100%">
<mx:columns>
<mx:DataGridColumn headerText="Nome" dataField="nome"/>
<mx:DataGridColumn headerText="Sobrenome" dataField="sobrenome"/>
<mx:DataGridColumn headerText="Fone" dataField="fone"/>
<mx:DataGridColumn headerText="§" width="40" textAlign="center">
<mx:itemRenderer>
<mx:Component>
<mx:Button label="X" width="8" click="outerDocument.removerContato()"/>
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
</mx:columns>
</mx:DataGrid>
 
<mx:Button id="b2" label="Adicionar Contato" click="addContato()"/>
</mx:Panel>
 
</mx:Application>

É isso aí, pessoal, espero ter ajudado. Qualquer dúvida podem deixar um comentário ou visitar o meu blog e até a próxima.

Exemplo Funcionando: