Mise en cache en Swift : Redis, Memcached et solutions intégrées
La mise en cache est l'un des outils clés pour améliorer les performances et la réactivité des applications Swift pour iOS et macOS. Dans cet article, nous analyserons trois approches principales : les solutions intégrées (NSCache, URLCache), ainsi que les systèmes externes (Redis et Memcached). Vous apprendrez quand et quel outil choisir, et obtiendrez des exemples de code prêts à l'emploi.
Pourquoi la mise en cache est-elle nécessaire dans les applications Swift ?
Sans mise en cache, chaque accès aux données (réseau, disque, base de données) charge le système et augmente le temps de réponse. Le cache permet de stocker les données fréquemment utilisées en mémoire vive, réduisant ainsi les latences et la charge sur le serveur. Pour les appareils mobiles, c'est particulièrement important : économie de trafic, de batterie et amélioration de l'UX.
1. Solutions intégrées : NSCache et URLCache
Apple fournit deux outils intégrés puissants : NSCache pour la mise en cache générale d'objets et URLCache pour la mise en cache des requêtes réseau.
NSCache
NSCache est un cache thread-safe qui gère automatiquement la mémoire. Il supprime les objets en cas de manque de mémoire, ce qui est idéal pour iOS.
import Foundation
class ImageCacheManager { static let shared = ImageCacheManager() private let cache = NSCache<NSString, UIImage>() private init() { cache.countLimit = 100 // Maximum 100 images 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 met automatiquement en cache les réponses HTTP. Il peut être configuré pour une session URLSession spécifique.
import Foundation
// Configuration 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)
// Exemple de requêtelet url = URL(string: "https://api.example.com/data")!let task = session.dataTask(with: url) { data, response, error in if let data = data { // Les données peuvent provenir du cache print("Reçu \\(data.count) octets") }}task.resume()2. Redis pour Swift : mise en cache côté serveur
Redis est une base de données in-memory, souvent utilisée pour la mise en cache côté serveur. Pour Swift, il existe la bibliothèque populaire Vapor Redis (pour Vapor) ou RediStack (pour tout projet).
Exemple avec RediStack
import RediStackimport NIOCoreimport NIOPosix
// Connexion à Redislet eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1)let connection = try RedisConnection.make( configuration: .init(hostname: "localhost", port: 6379), boundEventLoop: eventLoopGroup.next()).wait()
// Définition d'une valeurtry connection.set("user:123", to: "{\\"name\\": \\"Alice\\", \\"age\\": 30}").wait()
// Récupération d'une valeurlet result = try connection.get("user:123", as: String.self).wait()print("Reçu de Redis : \\(result ?? "nil")")
// Fermeture de la connexiontry connection.close().wait()try eventLoopGroup.syncShutdownGracefully()