Almacenamiento en caché en Swift: Redis, Memcached y soluciones integradas
El almacenamiento en caché es una de las herramientas clave para mejorar el rendimiento y la capacidad de respuesta de las aplicaciones en Swift para iOS y macOS. En este artículo, analizaremos tres enfoques principales: soluciones integradas (NSCache, URLCache), así como sistemas externos (Redis y Memcached). Aprenderá cuándo y qué herramienta elegir, y obtendrá ejemplos de código listos para usar.
¿Por qué es necesario el almacenamiento en caché en aplicaciones Swift?
Sin almacenamiento en caché, cada acceso a datos (red, disco, base de datos) carga el sistema y aumenta el tiempo de respuesta. La caché permite almacenar datos de uso frecuente en la memoria RAM, reduciendo las demoras y la carga en el servidor. Para dispositivos móviles, esto es especialmente importante: ahorro de tráfico, batería y mejora de la experiencia de usuario.
1. Soluciones integradas: NSCache y URLCache
Apple proporciona dos potentes herramientas integradas: NSCache para almacenamiento en caché general de objetos y URLCache para almacenamiento en caché de solicitudes de red.
NSCache
NSCache es una caché segura para subprocesos que administra la memoria automáticamente. Elimina objetos cuando hay poca memoria, lo que es ideal para iOS.
import Foundation
class ImageCacheManager { static let shared = ImageCacheManager() private let cache = NSCache<NSString, UIImage>() private init() { cache.countLimit = 100 // Máximo 100 imágenes cache.totalCostLimit = 50 * 1024 * 1024 // 50 MB } func getImage(for key: String) -> UIImage? { return cache.object(forKey: key as NSString) } func setImage(_ image: UIImage, for key: String, cost: Int = 0) { cache.setObject(image, forKey: key as NSString, cost: cost) } func removeImage(for key: String) { cache.removeObject(forKey: key as NSString) } func clearCache() { cache.removeAllObjects() }}URLCache
URLCache almacena en caché automáticamente las respuestas HTTP. Se puede configurar para una sesión específica de URLSession.
import Foundation
// Configuración de URLCachelet memoryCapacity = 50 * 1024 * 1024 // 50 MBlet diskCapacity = 100 * 1024 * 1024 // 100 MBlet cache = URLCache(memoryCapacity: memoryCapacity, diskCapacity: diskCapacity, diskPath: "myCache")
let configuration = URLSessionConfiguration.defaultconfiguration.urlCache = cacheconfiguration.requestCachePolicy = .returnCacheDataElseLoad
let session = URLSession(configuration: configuration)
// Ejemplo de solicitudlet url = URL(string: "https://api.example.com/data")!let task = session.dataTask(with: url) { data, response, error in if let data = data { // Los datos pueden provenir de la caché print("Recibidos \\(data.count) bytes") }}task.resume()2. Redis para Swift: almacenamiento en caché del lado del servidor
Redis es una base de datos en memoria, utilizada a menudo para almacenamiento en caché del lado del servidor. Para Swift, existen bibliotecas populares como Vapor Redis (para Vapor) o RediStack (para cualquier proyecto).
Ejemplo con RediStack
import RediStackimport NIOCoreimport NIOPosix
// Conexión a Redislet eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1)let connection = try RedisConnection.make( configuration: .init(hostname: "localhost", port: 6379), boundEventLoop: eventLoopGroup.next()).wait()
// Establecer valortry connection.set("user:123", to: "{\\"name\\": \\"Alice\\", \\"age\\": 30}").wait()
// Obtener valorlet result = try connection.get("user:123", as: String.self).wait()print("Obtenido de Redis: \\(result ?? "nil")")
// Cerrar conexióntry connection.close().wait()try eventLoopGroup.syncShutdownGracefully()