Caching en Swift: Redis, Memcached y soluciones integradas: de la A a la Z
El caching es una de las estrategias clave para optimizar el rendimiento en aplicaciones iOS y macOS. En este artículo, analizaremos en detalle cómo organizar el caching en Swift: desde el NSCache integrado hasta el trabajo con sistemas externos como Redis y Memcached. Aprenderá cuándo elegir cada herramienta y obtendrá ejemplos de código listos para usar para cada enfoque.
¿Por qué es necesario el caching en aplicaciones Swift?
Cualquier aplicación que trabaje con solicitudes de red, bases de datos o cálculos pesados puede beneficiarse del caching. Las principales ventajas son:
- Velocidad: los datos de la caché se devuelven en milisegundos, sin demoras de red o disco.
- Ahorro de tráfico: menos solicitudes al servidor significa menos costos para el usuario y el servidor.
- Acceso sin conexión: con una implementación adecuada, parte de la funcionalidad funciona sin internet.
- Reducción de la carga del servidor: especialmente relevante para soluciones Swift del lado del servidor (Vapor, Kitura).
Soluciones integradas: NSCache y URLCache
NSCache — caching ligero en memoria
NSCache es una clase integrada en Foundation para el almacenamiento temporal de pares "clave-valor". Elimina automáticamente objetos cuando hay falta de memoria, lo que lo hace ideal para almacenar en caché imágenes, respuestas JSON y otros datos no 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("Datos de la caché: \\(cachedData.count) bytes")}Características:
- Gestión automática de memoria: no es necesario eliminar objetos manualmente.
- Seguro para hilos: se puede usar desde diferentes hilos.
- No garantiza la persistencia de datos: el sistema puede vaciar la caché.
URLCache — caching de solicitudes HTTP
URLCache proporciona caching a nivel de solicitudes de red. Funciona con URLSession y guarda automáticamente las respuestas del servidor.
import Foundation
// Configuración de la cachélet memoryCapacity = 50 * 1024 * 1024 // 50 MBlet diskCapacity = 100 * 1024 * 1024 // 100 MBlet urlCache = URLCache(memoryCapacity: memoryCapacity, diskCapacity: diskCapacity, diskPath: "myCache")
URLCache.shared = urlCache
// Configuración de la sesiónlet config = URLSessionConfiguration.defaultconfig.requestCachePolicy = .returnCacheDataElseLoadconfig.urlCache = urlCache
let session = URLSession(configuration: config)
// Ejecución de la solicitudlet url = URL(string: "https://api.example.com/data")!let task = session.dataTask(with: url) { data, response, error in if let data = data { print("Recibidos \\(data.count) bytes") // Los datos se almacenan en caché automáticamente }}task.resume()Para un ajuste fino del caching, utilice los encabezados HTTP y las políticas Cache-Control del lado del servidor.
Redis en Swift: caching del lado del servidor
Redis es un almacén de pares "clave-valor" en memoria de alto rendimiento. Para desarrolladores Swift que trabajan con frameworks del lado del servidor (Vapor, Perfect), Redis es la opción estándar para el caching.