Caching in Swift (iOS/macOS): Redis, NSCache, and Core Data

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Caching in Swift (iOS/macOS): Redis and Alternatives



Caching is one of the key mechanisms for optimizing the performance of mobile and desktop applications in Swift. It allows you to reduce data loading time, decrease server load, and improve user experience. In this article, we will look at the main caching tools for iOS and macOS: from built-in solutions (NSCache, URLCache) to integration with external systems (Redis) and persistent storage (Core Data).



1. Built-in Caching Mechanisms



1.1 NSCache — Fast In-Memory Cache

NSCache is a thread-safe, automatically purging cache, ideal for temporary storage of objects that can be recreated (e.g., images or parsing results).

import Foundation

let imageCache = NSCache<NSString, UIImage>()

func loadImage(from url: URL, completion: @escaping (UIImage?) -> Void) { let cacheKey = url.absoluteString as NSString

// Check cache if let cachedImage = imageCache.object(forKey: cacheKey) { completion(cachedImage) return }

// Load data URLSession.shared.dataTask(with: url) { data, _, _ in guard let data = data, let image = UIImage(data: data) else { completion(nil) return } // Save to cache imageCache.setObject(image, forKey: cacheKey) completion(image) }.resume()}

Features:

  • Automatically removes objects when memory is low (supports countLimit and totalCostLimit).
  • Ideal for caching downloaded images, API JSON responses.
  • Does not persist data between app launches.


1.2 URLCache — System HTTP Request Cache

URLCache provides transparent caching of network requests at the system level. Supports disk and memory storage.

let cache = URLCache(memoryCapacity: 50 * 1024 * 1024,   // 50 MB                     diskCapacity: 200 * 1024 * 1024,     // 200 MB                     diskPath: "myCache")URLCache.shared = cache

// Example request with cachinglet request = URLRequest(url: URL(string: "https://api.example.com/data")!, cachePolicy: .returnCacheDataElseLoad, timeoutInterval: 30)URLSession.shared.dataTask(with: request) { data, response, error in // Data will be automatically cached}.resume()

This method works well for static resources (images, configuration files), but is not suitable for dynamic data that requires freshness.



2. Persistent Caching with Core Data

If you need to persist data between app sessions, use Core Data or SQLite (via GRDB.swift). Below is a simple cache example using Core Data:

import CoreData

class CacheManager { static let shared = CacheManager() private let context: NSManagedObjectContext

private init() { // Core Data stack setup (simplified) let container = NSPersistentContainer(name: "CacheModel") container.loadPersistentStores { _, error in if let error = error { fatalError("Core Data error: \\(error)") } } context = container.viewContext }

func save(data: Data, forKey key: String) { let entity = CachedItem(context: context) entity.key = key entity.data = data entity.timestamp = Date() try? context.save() }

func load(forKey key: String) -> Data? { let fetch: NSFetchRequest<CachedItem> = CachedItem.fetchRequest() fetch.predicate = NSPredicate(format: "key == %@", key) let result = try? context.fetch(fetch)

Recommendations