Кэширование в Swift: Redis, Memcached и встроенные решения
Кэширование — один из ключевых инструментов для повышения производительности и отзывчивости приложений на Swift для iOS и macOS. В этой статье мы разберем три основных подхода: встроенные решения (NSCache, URLCache), а также внешние системы (Redis и Memcached). Вы узнаете, когда и какой инструмент выбрать, и получите готовые примеры кода.
Зачем нужно кэширование в Swift-приложениях?
Без кэширования каждое обращение к данным (сеть, диск, база данных) загружает систему и увеличивает время отклика. Кэш позволяет хранить часто используемые данные в оперативной памяти, сокращая задержки и нагрузку на сервер. Для мобильных устройств это особенно важно: экономия трафика, батареи и улучшение UX.
1. Встроенные решения: NSCache и URLCache
Apple предоставляет два мощных встроенных инструмента: NSCache для общего кэширования объектов и URLCache для кэширования сетевых запросов.
NSCache
NSCache — это потокобезопасный кэш, автоматически управляющий памятью. Он удаляет объекты при нехватке памяти, что идеально для 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 автоматически кэширует HTTP-ответы. Его можно настроить для конкретного сеанса URLSession.
import Foundation
// URLCache configurationlet 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)
// Example requestlet url = URL(string: "https://api.example.com/data")!let task = session.dataTask(with: url) { data, response, error in if let data = data { // Data may come from cache print("Received \\(data.count) bytes") }}task.resume()2. Redis для Swift: кэширование на стороне сервера
Redis — это in-memory база данных, часто используемая для кэширования на серверной стороне. Для Swift существует популярная библиотека Vapor Redis (для Vapor) или RediStack (для любых проектов).
Пример с RediStack
import RediStackimport NIOCoreimport NIOPosix
// Connection to Redislet eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1)let connection = try RedisConnection.make( configuration: .init(hostname: "localhost", port: 6379), boundEventLoop: eventLoopGroup.next()).wait()
// Setting a valuetry connection.set("user:123", to: "{\\"name\\": \\"Alice\\", \\"age\\": 30}").wait()
// Getting a valuelet result = try connection.get("user:123", as: String.self).wait()print("Retrieved from Redis: \\(result ?? "nil")")
// Closing connectiontry connection.close().wait()try eventLoopGroup.syncShutdownGracefully()