عندما يعمل الكود على المحاكي لكنه يتعطل على الجهاز الحقيقي: فهم UI_USER_INTERFACE_IDIOM() في Swift
\n\nهل سبق لك أن كتبت تطبيقًا يبدو مثاليًا على محاكي iPhone 14 Pro، لكنه يتحول إلى فوضى على iPad Mini؟ أو العكس - واجهة iPad العصرية الخاصة بك تنزلق على iPod touch القديم؟ ألم مألوف، أليس كذلك؟
\n\nغالبًا ما يواجه مطورو iOS الحاجة إلى معرفة الجهاز الذي يعمل عليه التطبيق. قد يبدو الأمر بسيطًا، لكن الشيطان يكمن في التفاصيل كما هو الحال دائمًا. السؤال الأسطوري على Stack Overflow حول UI_USER_INTERFACE_IDIOM() حصد آلاف المشاهدات، مما يعني أنه حتى المبرمجين المتمرسين يخلطون أحيانًا بين التفاصيل الدقيقة.
في هذه المقالة، سنشرح كل ما تحتاج معرفته حول تحديد الجهاز في Swift. لا ماء - فقط ممارسة وأمثلة حية وإجابات على الأسئلة الأكثر شيوعًا.
\n\nما هو UI_USER_INTERFACE_IDIOM() ولماذا يتم الحديث عنه؟
\n\nهذه دالة قديمة وجيدة من عصر Objective-C. تُرجع قيمة من نوع UIUserInterfaceIdiom، والتي تشير إلى نوع الجهاز الذي نتعامل معه: iPhone، iPad، TV أو CarPlay.
هذا ما كان يبدو عليه الأمر في Objective-C الكلاسيكي:
\n\nif (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {\n // هذا iPad\n} else {\n // هذا iPhone أو iPod touch\n}\n\nلكن Swift هي لغة أكثر صرامة وأمانًا. الاستخدام المباشر لهذه الدالة C ليس دائمًا مناسبًا. ظهر نهج أكثر حداثة من خلال UIDevice.current.
كيفية تحديد الجهاز بشكل صحيح في Swift: طريقتان عمليتان
\n\nالطريقة رقم 1 - الكلاسيكية عبر UIDevice (موصى بها):
import UIKit\n\nlet deviceIdiom = UIDevice.current.userInterfaceIdiom\n\nswitch deviceIdiom {\ncase .phone:\n print("هذا iPhone أو iPod touch")\ncase .pad:\n print("هذا iPad")\ncase .tv:\n print("هذا Apple TV")\ncase .carPlay:\n print("هذا CarPlay")\ncase .mac:\n print("هذا Mac Catalyst أو Mac")\n@unknown default:\n print("جهاز غير معروف (ربما مستقبلي)")\n}\n\nهام: حالة .mac ظهرت في iOS 14+. إذا كان تطبيقك يدعم إصدارات أقدم، استخدم @unknown default لمعالجة الأنواع المستقبلية.
الطريقة رقم 2 - التوافق مع كود Objective-C (إذا لزم الأمر):
\n\nif UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.phone {\n print("نعمل على هاتف")\n}\n\nكلا الخيارين صحيحان، لكن الأول أكثر توافقًا مع أسلوب Swift.
\n\nالأسئلة الشائعة والمزالق
\n\n1. لماذا يتم تحديد iPhone على iPad mini؟
\n\nهذا هو السؤال الأكثر شيوعًا. تقوم بتشغيل التطبيق على iPad mini، لكن userInterfaceIdiom يعيد باستمرار .phone. ما المشكلة؟
الإجابة بسيطة وغير واضحة: وضع القياس (Scale Mode). إذا تم تحديد وضع "iPhone" في إعدادات تطبيقك (Target → General → Deployment Info)، فحتى على iPad الفعلي، سيحاكي النظام iPhone.
\n\nالحل: تحقق من إعدادات المشروع.
\n- \n
- اذهب إلى Target الخاص بتطبيقك \n
- General → Deployment Info \n
- Devices: اختر "Universal" (إذا كان يجب أن يعمل التطبيق على جميع الأجهزة) \n
إذا اخترت "iPhone Only"، فسيعمل التطبيق على iPad في وضع التوافق (كما لو كان iPhone كبيرًا)، وسيكون idiom هو .phone.
2. كيف نميز بين iPhone و iPod touch؟
\n\nUI_USER_INTERFACE_IDIOM() لا يفرق بين iPhone و iPod touch - كلاهما يعيد .phone. للتحديد الدقيق للطراز، يجب استخدام UIDevice.current.model أو modelName عبر sysctl.
مثال على امتداد للحصول على اسم الطراز الدقيق:
\n\nimport UIKit\n\nextension UIDevice {\