BLOG

Acompanhe a Mobits pelo RSS

FILTROS

Se você pretende carregar uma imagem ou qualquer outro recurso vindo da Internet de forma repetitiva e com pouca ou nenhuma variação de seu conteúdo, é bem provável que você precise de alguma técnica de cache. Sem o cache, é provável que seu aplicativo perca muito tempo carregando o mesmo recurso remoto desnecessariamente.

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.

COMPARTILHE

DEIXE UM COMENTÁRIO

If you can read this, you don't use a typical webbrowser that plays nice with CSS.
Please do not fill in anything here!