O framework SDWebImage fornece uma solução robusta para carregamento e cache de imagens em aplicativos iOS. Sua arquitetura é construída em torno de três componentes principais que trabalham em conjunto de forma eficiente: o SDWebImageManager, o SDImageCache e o SDWebImageDownloader. Este artigo explora em detalhe a estrutura, funcionalidades e a interação entre estes módulos.
SDWebImageManager: O Coordenador Central
O SDWebImageManager atua como o ponto de entrada e orquestrador principal para o carregamento de imagens. Ele abstrai a complexidade de coordenar operações de cache e rede, oferecendo uma API unificada. Internamente, ele gerencia um ciclo de vida completo para cada solicitação, desde a verificação em cache até a conclusão da transferência via rede.
Funcionalidades Principais
O manager oferece uma interface de alto nível para carregar imagens, permitindo configurações avançadas como opções de cache, calbacks de progresso e transformações.
// Exemplo de uso básico do SDWebImageManager
SDWebImageManager *gestor = [SDWebImageManager sharedManager];
[gestor loadImageWithURL:localDaImagem
opcoes:SDWebImageRetryFailed
progresso:^(NSInteger bytesRecebidos, NSInteger totalEsperado, NSURL *urlAlvo) {
// Atualização do progresso
}
concluido:^(UIImage *imagem, NSData *dados, NSError *erro,
SDImageCacheType tipoDoCache, BOOL finalizado, NSURL *url) {
if (imagem) {
// Imagem carregada com sucesso
} else {
// Tratar erro
}
}];
Uma característica importante é o mecanismo de geração de chave de cache, que pode ser personalizado para controlar a identificação das imagens no sistema de cache.
// Definição de um filtro de chave de cache customizado
gestor.filtroChaveCache = [SDWebImageCacheKeyFilter cacheKeyFilterWithBlock:^NSString *(NSURL *url) {
NSURLComponents *componentes = [NSURLComponents componentsWithURL:url resolvingAgainstBaseURL:NO];
componentes.query = nil; // Ignora parâmetros de consulta para a chave
return componentes.URL.absoluteString;
}];
Estratégia de Cache em Camadas
O manager implementa uma pesquisa em cache com prioridade: primeiro verifica a memória (rápido, mas volátil), depois o disco (persistente, mas mais lento) e, por fim, recorre à rede (mais lento, requer conectividade).
Opções Avançadas
O componente suporta um processador de opções global, que permite ajustar parâmetros com base na URL da imagem ou em outros critérios.
// Configuração de um processador de opções
gestor.processadorOpcoes = [SDWebImageOptionsProcessor optionsProcessorWithBlock:^SDWebImageOptionsResult *(NSURL *url, SDWebImageOptions opcoes, SDWebImageContext *contexto) {
SDWebImageContextMutable *contextoMutavel = [contexto mutableCopy];
// Ajuste de opções baseado na extensão do arquivo
if ([[url.pathExtension lowercaseString] isEqualToString:@"gif"]) {
opcoes |= SDWebImageAvoidDecodeImage; // Evita decodificação prematura para GIFs
}
contextoMutavel[SDWebImageContextImageScaleFactor] = @([UIScreen mainScreen].scale);
return [[SDWebImageOptionsResult alloc] initWithOptions:opcoes context:[contextoMutavel copy]];
}];
O manager também lida com falhas, mantendo uma lista de URLs que falharam para evitar requisições repetidas inúteis.
SDImageCache: Sistema de Cache Inteligente
O SDImageCache é responsável por armazenar e recuperar imagens de forma eficiente. Ele gerencia duas camadas de cache: memória (usando NSCache) e disco.
Configuração do Cache
O comportamento do cache é altamente configurável através do objeto SDImageCacheConfig.
// Configuração personalizada para uma instância de cache
SDImageCacheConfig *configCache = [SDImageCacheConfig defaultCacheConfig];
configCache.maxIdadeDisco = 60 * 60 * 24 * 7; // 7 dias
configCache.maxTamanhoDisco = 100 * 1024 * 1024; // 100 MB
configCache.deveCacheImagensNaMemoria = YES;
SDImageCache *cacheCustomizado = [[SDImageCache alloc] initWithNamespace:@"app_custom"
diretorioCacheDisco:nil
config:configCache];
Operações de Armazenamento e Recuperação
O cache permite armazenar e buscar imagens de forma síncrona (apenas memória) ou assíncrona (incluindo disco).
// Busca síncrona na memória
UIImage *imagemMemoria = [cacheCustomizado imageFromMemoryCacheForKey:chave];
// Busca assíncrona completa (memória + disco)
[cacheCustomizado queryImageForKey:chave
opcoes:0
contexto:nil
tipoCache:SDImageCacheTypeAll
completion:^(UIImage * _Nullable img, NSData * _Nullable dados, SDImageCacheType tipo) {
if (img) {
// Imagem encontrada no cache (tipo 'tipo')
}
}];
Políticas de Limpeza
O cache oferece métodos para liberar memória e gerenciar o espaço em disco, removendo entradas antigas ou quando o limite de tamanho é atingido.
// Liberar cache de memória
[cacheCustomizado clearMemory];
// Limpar cache de disco em segundo plano
[cachecustomizado cleanDiskWithCompletionBlock:^{
NSLog(@"Limpeza do cache de disco concluída.");
}];
SDWebImageDownloader: Motor de Transferência de Rede
O SDWebImageDownloader gerencia as operações assíncronas de download de imagens da web. Ele utiliza NSURLSession e gerencia uma fila de operações (NSOperationQueue) para controlar a concorrência.
Configuração do Downloader
O downloader é altamente configurável, permitindo definir timeouts, limites de concorrência, políticas de execução e manipuladores de requisição.
// Criação de um downloader com configuração personalizada
SDWebImageDownloaderConfig *configDownloader = [SDWebImageDownloaderConfig defaultDownloaderConfig];
configDownloader.maxDownloadsConcorrentes = 4;
configDownloader.timeoutDownload = 20.0;
configDownloader.ordemExecucao = SDWebImageDownloaderLIFOExecutionOrder; // Último a chegar, primeiro a sair
SDWebImageDownloader *downloaderCustomizado = [[SDWebImageDownloader alloc] initWithConfig:configDownloader];
// Adicionar um cabeçalho de autenticação a todas as requisições
downloaderCustomizado.modificadorRequisicao = ^NSURLRequest * _Nullable(NSURLRequest * _Nonnull requisicaoOriginal) {
NSMutableURLRequest *requisicaoMutavel = [requisicaoOriginal mutableCopy];
[requisicaoMutavel setValue:@"Bearer TOKEN_ACESSO" forHTTPHeaderField:@"Authorization"];
return [requisicaoMutavel copy];
};
Realizando um Download
A interface principal retorna um token que pode ser usado para cancelar a operação.
// Iniciar download com callbacks de progresso e conclusão
SDWebImageDownloadToken *token = [downloaderCustomizado downloadImageWithURL:urlImagem
opcoes:SDWebImageDownloaderHighPriority
progresso:^(NSInteger recebido, NSInteger esperado, NSURL * _Nullable url) {
float progresso = (float)recebido / esperado;
}
concluido:^(UIImage * _Nullable imagem, NSData * _Nullable dados, NSError * _Nullable erro, BOOL finalizado) {
if (imagem && finalizado) {
// Download concluído com sucesso
} else if (erro) {
// Tratar erro na rede
}
}];
// Cancelar o download, se necessário
[token cancel];
O downloader inclui um tratamento robusto de erros, categorizando falhas de rede, URLs inválidas ou dados corrompidos.
Colaboração entre Componentes
Os três componentes interagem de forma síncrona. O SDWebImageManager orquestra o fluxo: primeiro cosnulta o SDImageCache. Se a imagem não for encontrada, utiliza o SDWebImageDownloader para obtê-la da rede. Após o download bem-sucedido, a imagem é passada por um pipeline de transformação (se configurado) e então armazenada no cache para uso futuro.
Este fluxo é otimizado para performance, empregando operações em threads secundárias, gerenciamento eficiente de memória, reutilização de conexões de rede e controle de concorrência. A modularidade da arquitetura permite que desenvolvedores substituam ou estendam componentes individuais (como cache ou downloader) para atender a requisitos específicos.