لماذا نحتاج إلى ملف ثوابت عامة في Swift؟
\n\nكل مطور iOS واجه مرة واحدة على الأقل في حياته موقفًا تكون فيه نفس القيم — عنوان URL للخادم، مفاتيح API، معرفات الخلايا، الهوامش — موزعة في جميع أنحاء المشروع. وفجأة يقول المدير: "غيّر عنوان URL الأساسي". تفتح المشروع وتبدأ المهمة: البحث عن جميع تكرارات "https://old.api.com" واستبدالها بالجديد. هل هذا مألوف؟
لهذا السبب بالتحديد نحتاج إلى ملف الثوابت العامة في Swift — مكان واحد يتم فيه تخزين جميع "الأرقام السحرية" والسلاسل النصية. في هذه المقالة، سنحلل الأسئلة الأكثر شيوعًا من Stack Overflow (الموضوع حصل على آلاف المشاهدات!) وسنقدم إجابات واضحة مع أمثلة كود. فلنبدأ!
\n\nالسؤال 1: كيف يمكن إنشاء ملف ثوابت بسيط في Swift؟
\n\nالطريقة الأكثر مباشرة هي استخدام struct مع خصائص ثابتة (static). لماذا struct وليس class؟ لأن الهياكل هي أنواع قيمية (value types)، فهي أخف ولا تتطلب مُهيئًا (initializer).
// Constants.swift\nimport Foundation\n\nstruct AppConstants {\n static let baseURL = "https://api.myapp.com/v1"\n static let apiKey = "your-secret-key-here"\n static let defaultTimeout: TimeInterval = 30.0\n static let maxRetryCount = 3\n}\n\nالاستخدام بسيط: AppConstants.baseURL. هذا كل شيء، لا مزيد من السلاسل السحرية. ثوابت Swift مع let تضمن عدم تغيير القيمة عن طريق الخطأ.
لماذا لا نستخدم المتغيرات العامة (global variables)؟
\n\nيمكنك بالطبع كتابة:
\n\nlet baseURL = "https://api.myapp.com/v1"\n\nلكن هذه هي ملف الثوابت العامة في Swift في أبسط صوره. المشكلة: لا يوجد نطاق أسماء (namespace). إذا كان لديك 50 ثابتًا، فسوف ترتبك بسرعة أي ثابت ينتمي إلى ماذا. struct يحل هذه المشكلة بأناقة.
السؤال 2: Enum أم Struct — أيهما تختار للثوابت؟
\n\nعلى Stack Overflow، تدور نقاشات حامية. دعنا نحلل كلا النهجين.
\n\nStruct (الخيار الشائع)
\n\nstruct UIConstants {\n static let cornerRadius: CGFloat = 12.0\n static let defaultPadding: CGFloat = 16.0\n static let animationDuration: Double = 0.3\n}\n\nالإيجابيات: مألوف، يمكن إنشاء نسخ (على الرغم من أن ذلك غير مطلوب عادةً)، سهل التوسيع باستخدام extension.
\n\nالسلبيات: من الناحية الفنية يمكن كتابة UIConstants()، وهو أمر لا معنى له.
Enum (الخيار الأكثر صرامة)
\n\nenum NetworkConstants {\n static let baseURL = "https://api.myapp.com/v1"\n static let apiVersion = "2.0"\n static let defaultHeaders: [String: String] = [\n "Content-Type": "application/json"\n ]\n}\n\nالإيجابيات: لا يمكن إنشاء نسخة — المترجم (compiler) لن يسمح بذلك. نطاق أسماء نقي. مثالي لـ ثوابت التعداد في Swift.
\n\nالسلبيات: يعتبرها البعض "اختراقًا" — استخدام التعداد (enum) ليس لغرضه الأساسي.
\n\nحكمي: إذا كنت تريد أن تكون مطورًا "صحيحًا" وتحمي نفسك من إنشاء نسخة عن طريق الخطأ — استخدم enum. إذا كنت تعمل في فريق اعتاد الجميع فيه على struct — استخدم struct. كلا الخيارين صحيحان.
السؤال 3: كيف تنظم الثوابت حسب الفئات؟
\n\nعندما يكبر المشروع، يتحول ملف واحد إلى مزبلة. الحل — هياكل متداخلة أو ملفات منفصلة لكل فئة.
\n\nالخيار A: هياكل متداخلة (في ملف واحد)
\n\nstruct Constants {\n struct Network {\n static let baseURL = "https://api.myapp.com"\n static let timeout: TimeInterval = 30\n }\n \n struct UI {\n static let cornerRadius: CGFloat = 8\n static let buttonHeight: CGFloat = 44\n }\n \n struct Storage {\n static let userDefaultsKey = "com.myapp.user"\n static let maxCacheSize =