مقدمة: لماذا التخزين المؤقت هو مفتاح أداء تطبيقات Swift
\n\nفي التطوير الحديث باستخدام Swift، سواء كان تطبيق iOS أو حلاً خادمياً على Vapor، تعتمد سرعة العمل واستجابة الواجهة بشكل مباشر على الإدارة الذكية للبيانات. التخزين المؤقت ليس مجرد "تذكر" النتائج، بل هو علم كامل حول كيفية تقليل وقت الوصول إلى البيانات، وتقليل الحمل على الشبكة وقاعدة البيانات، وضمان عمل سلس حتى تحت الأحمال القصوى.
\n\nعلى المستوى المتقدم، يواجه مطورو Swift خياراً: استخدام الآليات المدمجة (NSCache, URLCache) أو ربط أنظمة خارجية مثل Redis وMemcached. لكل من هذه الأدوات بنيته الخاصة ومجال تطبيقه. في هذه المقالة، سنشرح كيفية دمج هذه الحلول والجمع بينها بفعالية في نظام Swift البيئي.
\n\n1. الحلول المدمجة: NSCache وURLCache
\n\n1.1 NSCache - ذاكرة تخزين مؤقت خفيفة للكائنات
\n\nNSCache هو قاموس آمن للخيوط، مدمج في Foundation. إنه مثالي لتخزين الكائنات التي يكون إنشاؤها أو تحميلها مكلفاً (مثل الصور، نتائج الحسابات المعقدة). الميزة الرئيسية هي التنظيف التلقائي عند نقص الذاكرة، وهو أمر بالغ الأهمية لتطبيقات الأجهزة المحمولة.
import Foundation\n\nfinal class ImageCache {\n static let shared = ImageCache()\n private let cache = NSCache<NSString, UIImage>()\n \n private init() {\n cache.countLimit = 100 // الحد الأقصى 100 كائن\n cache.totalCostLimit = 50 * 1024 * 1024 // 50 ميجابايت\n }\n \n func getImage(for key: String) -> UIImage? {\n return cache.object(forKey: key as NSString)\n }\n \n func setImage(_ image: UIImage, for key: String, cost: Int? = nil) {\n if let cost = cost {\n cache.setObject(image, forKey: key as NSString, cost: cost)\n } else {\n cache.setObject(image, forKey: key as NSString)\n }\n }\n \n func removeImage(for key: String) {\n cache.removeObject(forKey: key as NSString)\n }\n \n func clearAll() {\n cache.removeAllObjects()\n }\n}\n\nملاحظات مهمة:
\n- \n
countLimitوtotalCostLimitهما توصيات وليست قيوداً صارمة. النظام هو من يقرر متى يحذف الكائنات. \n - يجب أن تكون المفاتيح من نوع
NSStringوليسString(يقوم Swift بتحويلها تلقائياً، لكن من الأفضل التحويل الصريح). \n - لا يُنصح باستخدام
NSCacheللبيانات الكبيرة التي لا تسع في الذاكرة. \n
1.2 URLCache - تخزين مؤقت لطلبات الشبكة
\n\nURLCache هو ذاكرة تخزين مؤقت نظامية لطلبات HTTP. يقوم تلقائياً بحفظ استجابات الخادم (مع مراعاة رؤوس Cache-Control) وإعادتها دون الاتصال بالشبكة. يسمح التكوين بالتحكم في حجم الذاكرة والقرص.
import Foundation\n\n// إعداد URLCache للتطبيق بأكمله\nlet memoryCapacity = 20 * 1024 * 1024 // 20 ميجابايت\nlet diskCapacity = 100 * 1024 * 1024 // 100 ميجابايت\nlet cache = URLCache(memoryCapacity: memoryCapacity, diskCapacity: diskCapacity, diskPath: "myCache")\nURLCache.shared = cache\n\n// مثال على الاستخدام مع URLSession\nlet config = URLSessionConfiguration.default\nconfig.requestCachePolicy = .returnCacheDataElseLoad // التخزين المؤقت أولاً، ثم الشبكة\nconfig.urlCache = cache\n\nlet session = URLSession(configuration: config)\nlet url = URL(string: "https://api.example.com/data")!\nlet task = session.dataTask(with: url) { data, response, error in\n // سيتم جلب البيانات من التخزين المؤقت إذا كانت موجودة ولم تنته صلاحيتها\n}\ntask.resume()\n\nنصيحة متقدمة: لتحديث التخزين المؤقت قسراً، استخدم السياسة .reloadIgnoringLocalCacheData، وللإدارة اليدوية استخدم الطرق cachedResponse(for:) وstoreCachedResponse(_:for:).