Cache em Swift: Redis, Memcached e soluções nativas: do A ao Z
Cache é uma das principais estratégias de otimização de desempenho em aplicativos iOS e macOS. Neste artigo, vamos detalhar como organizar o cache em Swift: desde o nativo NSCache até o trabalho com sistemas externos como Redis e Memcached. Você aprenderá quando escolher cada ferramenta e obterá exemplos de código prontos para cada abordagem.
Por que o cache é necessário em aplicativos Swift?
Qualquer aplicativo que trabalhe com requisições de rede, bancos de dados ou cálculos pesados pode se beneficiar do cache. Principais vantagens:
- Velocidade: dados do cache são retornados em milissegundos, sem atrasos de rede ou disco.
- Economia de tráfego: menos requisições ao servidor — menos custos para o usuário e o servidor.
- Acesso offline: com uma implementação correta, parte da funcionalidade funciona sem internet.
- Redução da carga no servidor: especialmente relevante para soluções Swift no servidor (Vapor, Kitura).
Soluções nativas: NSCache e URLCache
NSCache — cache leve em memória
NSCache é uma classe nativa do Foundation para armazenamento temporário de pares "chave-valor". Ela remove objetos automaticamente quando há falta de memória, tornando-a ideal para cache de imagens, respostas JSON e outros dados não críticos.
import Foundation
class ImageCacheManager { static let shared = ImageCacheManager() private let cache = NSCache<NSString, NSData>() func setImageData(_ data: Data, forKey key: String) { cache.setObject(data as NSData, forKey: key as NSString) } func getImageData(forKey key: String) -> Data? { return cache.object(forKey: key as NSString) as Data? } func removeAll() { cache.removeAllObjects() }}
// Usolet cache = ImageCacheManager.sharedcache.setImageData(imageData, forKey: "avatar_123")if let cachedData = cache.getImageData(forKey: "avatar_123") { print("Dados do cache: \\(cachedData.count) bytes")}Características:
- Gerenciamento automático de memória — não é necessário remover objetos manualmente.
- Thread-safe — pode ser usado de diferentes threads.
- Não garante a persistência dos dados — o cache pode ser limpo pelo sistema.
URLCache — cache de requisições HTTP
URLCache fornece cache no nível de requisições de rede. Ele funciona com URLSession e salva automaticamente as respostas do servidor.
import Foundation
// Configuração do cachelet memoryCapacity = 50 * 1024 * 1024 // 50 MBlet diskCapacity = 100 * 1024 * 1024 // 100 MBlet urlCache = URLCache(memoryCapacity: memoryCapacity, diskCapacity: diskCapacity, diskPath: "myCache")
URLCache.shared = urlCache
// Configuração da sessãolet config = URLSessionConfiguration.defaultconfig.requestCachePolicy = .returnCacheDataElseLoadconfig.urlCache = urlCache
let session = URLSession(configuration: config)
// Execução da requisiçãolet url = URL(string: "https://api.example.com/data")!let task = session.dataTask(with: url) { data, response, error in if let data = data { print("Recebidos \\(data.count) bytes") // Os dados são automaticamente armazenados em cache }}task.resume()Para ajuste fino do cache, use cabeçalhos HTTP e políticas Cache-Control no lado do servidor.
Redis em Swift: cache no servidor
Redis é um armazenamento de alto desempenho do tipo "chave-valor" em memória. Para desenvolvedores Swift que trabalham com frameworks de servidor (Vapor, Perfect), Redis é a escolha padrão para cache