التخزين المؤقت في Swift (iOS/macOS): Redis والبدائل
التخزين المؤقت هو أحد الآليات الرئيسية لتحسين أداء تطبيقات الأجهزة المحمولة وسطح المكتب المكتوبة بلغة Swift. فهو يسمح بتقليل وقت تحميل البيانات، وتخفيف الحمل على الخادم، وتحسين تجربة المستخدم. في هذه المقالة، سنستعرض أدوات التخزين المؤقت الرئيسية لنظامي iOS وmacOS: من الحلول المدمجة (NSCache، URLCache) إلى التكامل مع الأنظمة الخارجية (Redis) والتخزين الدائم (Core Data).
1. آليات التخزين المؤقت المدمجة
1.1 NSCache — تخزين مؤقت سريع في الذاكرة
NSCache هو ذاكرة تخزين مؤقت آمنة للخيوط، ويتم مسحها تلقائيًا، وهي مثالية للتخزين المؤقت للكائنات التي يمكن إعادة إنشائها (مثل الصور أو نتائج التحليل).
import Foundation
let imageCache = NSCache<NSString, UIImage>()
func loadImage(from url: URL, completion: @escaping (UIImage?) -> Void) { let cacheKey = url.absoluteString as NSString
// التحقق من التخزين المؤقت if let cachedImage = imageCache.object(forKey: cacheKey) { completion(cachedImage) return }
// تحميل البيانات URLSession.shared.dataTask(with: url) { data, _, _ in guard let data = data, let image = UIImage(data: data) else { completion(nil) return } // حفظ في التخزين المؤقت imageCache.setObject(image, forKey: cacheKey) completion(image) }.resume()}الميزات:
- يزيل الكائنات تلقائيًا عند نقص الذاكرة (يدعم
countLimitوtotalCostLimit). - مثالي للتخزين المؤقت للصور المحملة واستجابات JSON من API.
- لا يحتفظ بالبيانات بين عمليات تشغيل التطبيق.
1.2 URLCache — التخزين المؤقت النظامي لطلبات HTTP
URLCache يوفر تخزينًا مؤقتًا شفافًا لطلبات الشبكة على مستوى النظام. يدعم التخزين على القرص وفي الذاكرة.
let cache = URLCache(memoryCapacity: 50 * 1024 * 1024, // 50 MB diskCapacity: 200 * 1024 * 1024, // 200 MB diskPath: "myCache")URLCache.shared = cache
// مثال على طلب مع التخزين المؤقتlet request = URLRequest(url: URL(string: "https://api.example.com/data")!, cachePolicy: .returnCacheDataElseLoad, timeoutInterval: 30)URLSession.shared.dataTask(with: request) { data, response, error in // سيتم تخزين البيانات مؤقتًا تلقائيًا}.resume()تعمل هذه الطريقة بشكل ممتاز مع الموارد الثابتة (الصور، ملفات التكوين)، ولكنها غير مناسبة للبيانات الديناميكية التي تتطلب التحديث.
2. التخزين المؤقت الدائم باستخدام Core Data
إذا كنت بحاجة إلى حفظ البيانات بين جلسات التطبيق، استخدم Core Data أو SQLite (عبر GRDB.swift). فيما يلي مثال على تخزين مؤقت بسيط باستخدام Core Data:
import CoreData
class CacheManager { static let shared = CacheManager() private let context: NSManagedObjectContext
private init() { // إعداد Core Data stack (مبسط) 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)