Cache em Swift (iOS/macOS): Redis e outras ferramentas
Cache é uma das principais estratégias de otimização de desempenho para aplicativos móveis e desktop em Swift. Ele permite reduzir o tempo de carregamento de dados, diminuir a carga na rede e nos servidores, além de garantir o funcionamento do aplicativo no modo offline. No ecossistema Apple, estão disponíveis tanto mecanismos integrados (NSCache, URLCache) quanto soluções de terceiros, incluindo integração com Redis. Neste artigo, analisaremos detalhadamente as principais ferramentas de cache para iOS e macOS com exemplos de código.
1. Mecanismos de cache integrados no Foundation
NSCache — cache leve em memória
NSCache é um cache thread-safe e gerenciado automaticamente que remove objetos quando há falta de memória. Ideal para armazenamento temporário de imagens, dados de modelos ou resultados de cálculos.
import Foundation
let imageCache = NSCache<NSString, UIImage>()
// Definindo limitesimageCache.countLimit = 100 // Máximo de 100 objetosimageCache.totalCostLimit = 50 * 1024 * 1024 // 50 MB
// Salvandofunc cacheImage(_ image: UIImage, forKey key: String) { imageCache.setObject(image, forKey: key as NSString, cost: image.size.width * image.size.height * 4)}
// Recuperandofunc getCachedImage(forKey key: String) -> UIImage? { return imageCache.object(forKey: key as NSString)}Vantagens: simplicidade, limpeza automática, suporte a custo de objetos.
Desvantagens: cache apenas em memória, sem persistência.
URLCache — cache de requisições HTTP
URLCache armazena automaticamente em cache as respostas da URLSession. Funciona tanto em memória quanto em disco. Pode ser configurado globalmente ou para uma sessão específica.
import Foundation
// Configurando cache de 50 MB em memória e 100 MB em discolet cache = URLCache(memoryCapacity: 50 * 1024 * 1024, diskCapacity: 100 * 1024 * 1024, diskPath: "myCache")URLCache.shared = cache
// Usando com URLSessionlet config = URLSessionConfiguration.defaultconfig.urlCache = cacheconfig.requestCachePolicy = .returnCacheDataElseLoadlet session = URLSession(configuration: config)
let request = URLRequest(url: URL(string: "https://api.example.com/data")!)let task = session.dataTask(with: request) { data, response, error in // Os dados serão armazenados em cache automaticamente}task.resume()O gerenciamento da política de cache é feito através dos cabeçalhos Cache-Control do servidor ou do requestCachePolicy.
2. Cache de arquivos para acesso offline
Quando é necessário salvar dados entre execuções do aplicativo, utiliza-se o cache de arquivos no diretório Caches. É útil para JSON, imagens ou objetos serializados.
import Foundation
class FileCache { private let fileManager = FileManager.default private lazy var cacheDirectory: URL = { let paths = fileManager.urls(for: .cachesDirectory, in: .userDomainMask) return paths[0].appendingPathComponent("DataCache", isDirectory: true) }() init() { try? fileManager.createDirectory(at: cacheDirectory, withIntermediateDirectories: true) } func save(data: Data, forKey key: String) { let fileURL = cacheDirectory.appendingPathComponent(key) try? data.write(to: fileURL) } func load(forKey key: String) -> Data? { let fileURL = cacheDirectory.appendingPathComponent(key) return try? Data(contentsOf: fileURL) } func clearAll() { try? fileManager.removeItem(at: cacheDirectory) try? fileManager.createDirectory(at: cacheDirectory, withIntermediateDirectories: true) }}