28 Mar, 2011 17:54

Cache de recursos carregados da Internet

A solução que apresento aqui é relativamente simples, mas eficaz para gravar qualquer dado proveniente de um endereço na Internet e ainda possui a capacidade de administrar o cache antigo para evitar um armazenamento desnecessário de dados.

Cache Manager

A classe batizada de CacheManager possui 3 métodos principais:

  • - (void)gravarCache:(NSData *)data doEndereco:(NSString *)endereco que permite gravar um NSData e associá-lo a um endereço qualquer;
  • - (NSData *)cacheDoEndereco:(NSString *)endereco para recuperar o NSData associado previamente ao endereço dado;
  • - (void)limparCacheAntigo para apagar quaisquer arquivos de cache mais antigos que MAXIMA_IDADE_CACHE (em segundos).

CacheManager é um singleton definido utilizando a técnica descrita no excelente Cocoa with Love. Para obter uma instância de CacheManager, basta chamar:

[CacheManager sharedCacheManager]

Exemplo de uso

O post que eu escrevi sobre carregamento de imagens da Internet é uma boa base para aplicarmos o CacheManager. Veja como funcionava o método principal da classe UIImageViewRemota:

- (void)carregaImagemEmBackground {
    // carrega os dados da imagem
    NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:enderecoImagem]];
    UIImage *imagem = [[UIImage alloc] initWithData:data];
    [self performSelectorOnMainThread:@selector(exibeImagemCarregada:) withObject:imagem waitUntilDone:YES];
    [imagem release];
}

Com poucas modificações neste método, podemos torná-lo "cache enabled":

- (void)carregaImagemEmBackground {
    // solicita os dados do CacheManager
    NSData *data = [[CacheManager sharedCacheManager] cacheDoEndereco:enderecoImagem];
    if (!data) {
        // somente se não houver cache, fazemos o carregamento remoto
        data = [NSData dataWithContentsOfURL:[NSURL URLWithString:enderecoImagem]];
        [[CacheManager sharedCacheManager] gravarCache:data doEndereco:enderecoImagem];
    }

    UIImage *imagem = [[UIImage alloc] initWithData:data];
    [self performSelectorOnMainThread:@selector(exibeImagemCarregada:) withObject:imagem waitUntilDone:YES];
    [imagem release];
}

Simples, não?

Se você quiser que o aplicativo mantenha apenas o cache mais recente, basta modificar MAXIMA_IDADE_CACHE de acordo e, em qualquer ponto do código do seu aplicativo, rodar:

[[CacheManager sharedCacheManager] limparCacheAntigo];

Instalando

Se você gostou da técnica e pretende usá-la em seu aplicativo, baixe o projeto de exemplo e copie os arquivos CacheManager.h, CacheManager.m e SynthesizeSingleton.h para o seu projeto. Não esqueça de dar seu feedback, qualquer sugestão será benvinda.

Ao navegar neste site, você consente o uso de cookies nossos e de terceiros, que coletam informações anônimas e são essenciais para melhorar sua experiência em nosso site.