كيفية الحصول على مرجع إلى AppDelegate في Swift: من البسيط إلى المتقدم
إذا كنت قد كتبت أي تطبيق iOS باستخدام Swift، فمن المحتمل أنك واجهت موقفًا تحتاج فيه إلى الوصول إلى AppDelegate. قد يبدو الأمر بسيطًا، لكن هذا السؤال حصد آلاف المشاهدات على Stack Overflow، وليس من دون سبب. وراء البساطة الظاهرة تكمن طبقة كاملة من القرارات المعمارية التي تؤثر على أداء الكود وقابليته للصيانة.
في هذه المقالة، سنستعرض ليس فقط الطرق التقليدية للحصول على مرجع إلى AppDelegate، بل سنتحدث أيضًا عن متى يكون ذلك ضروريًا حقًا، ومتى يكون من الأفضل البحث عن بدائل. هيا بنا!
الطريقة التقليدية: UIApplication.shared.delegate
الطريقة الأكثر شيوعًا وربما الأبسط هي استخدام المفرد UIApplication.shared. يبدو الأمر كالتالي:
if let appDelegate = UIApplication.shared.delegate as? AppDelegate { // الآن لديك إمكانية الوصول إلى AppDelegate appDelegate.someMethod()}هذا الكود يعمل، لكن له بعض الملاحظات. أولاً، نقوم بتحويل النوع بشكل صريح، مما قد يؤدي إلى تعطل التطبيق إذا تبين أن delegate ليس من الفئة المتوقعة. ثانيًا، هذا النهج يخلق ارتباطًا قويًا في الكود. في عالم تطوير iOS الحديث، يعتبر هذا نمطًا معاكسًا، خاصة إذا كنت تستخدم SwiftUI أو SceneDelegate.
التحسين: إنشاء غلاف آمن
لتجنب كتابة تحويل النوع في كل مرة وتجنب المخاطرة، يمكنك إنشاء امتداد مناسب. هذا لا يبسط الكود فحسب، بل يزيد أيضًا من قابلية قراءته:
extension UIApplication { static var appDelegate: AppDelegate? { return shared.delegate as? AppDelegate }}
// الاستخدامif let appDelegate = UIApplication.appDelegate { appDelegate.performTask()}لاحظ أننا نستخدم static var، وليس خاصية محسوبة في كل مرة. هذا يحسن الأداء بشكل طفيف عند الاستدعاءات المتكررة. يقوم مترجم Swift بتحسين هذه الإنشاءات، وتحصل على وصول آمن دون حركات زائدة.
النهج البديل: عبر UIApplication.shared.delegate?.window??
أحيانًا يحاول المطورون الحصول على AppDelegate من خلال سلسلة window. يبدو الأمر كالتالي:
let appDelegate = UIApplication.shared.delegate?.window??.rootViewControllerبصراحة، هذه ليست أفضل ممارسة. أولاً، قد تكون window nil عند بدء تشغيل التطبيق. ثانيًا، يصعب قراءة وتصحيح مثل هذا الكود. الأداء أيضًا يتأثر - كل تداخل اختياري يتطلب فحوصات إضافية. من الأفضل استخدام الطريقة الأولى.
متى يكون الوصول إلى AppDelegate ضروريًا حقًا؟
قبل التوجه إلى UIApplication.shared.delegate، اسأل نفسك: "هل أحتاج هذا حقًا؟". غالبًا ما يُستخدم AppDelegate من أجل:
- إدارة دورة حياة التطبيق (بدء التشغيل، الانتقال إلى الخلفية، الإنهاء)
- إعداد الخدمات العامة (Core Data، Firebase، التحليلات)
- معالجة الإشعارات الفورية والروابط العميقة
لكن إذا كنت تحتاج فقط إلى نقل البيانات بين الشاشات أو استدعاء خدمة معينة، فإن AppDelegate هو اختيار خاطئ. من الأفضل استخدام حقن التبعية أو المفردات للخدمات المحددة.
SwiftUI و AppDelegate: نظرة جديدة
مع ظهور SwiftUI، تغير النهج المعماري. الآن لدينا @main وبروتوكول App. لكن ماذا لو كنت لا تزال بحاجة إلى الوصول إلى AppDelegate القديم؟ يمكنك استخدام UIApplicationDelegateAdaptor:
@mainstruct MyApp: App { @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene { Win