تخطَّ إلى المحتوى
Bahaa Taha — بهاء طه
تطوير التطبيقات10 دقائق قراءة١٬٢١١ كلمة

اكتشاف الأجهزة على الشبكة المحلية في iOS

أغلب حالات «لا يجد أي جهاز» ليست خللًا في الاكتشاف بل مفتاحًا ناقصًا في ملف الخصائص أو شبكة تعزل عملاءها — والترتيب الصحيح للإعداد.

Bahaa Taha — بهاء طهMrBebo
شاشة اعتماد أجهزة موثوقة قبل الاتصال بها على الشبكة المحلية
شاشة اعتماد أجهزة موثوقة قبل الاتصال بها على الشبكة المحلية

الإجابة المختصرة

الوصول إلى الشبكة المحلية في iOS يحتاج ثلاثة أشياء مجتمعة: مفتاح NSLocalNetworkUsageDescription في ملف الخصائص، وإعلان أنواع الخدمات في NSBonjourServices بأسمائها الكاملة، وموافقة المستخدم عند أول محاولة. نسيان إعلان خدمة يعيد قائمة فارغة دون أي رسالة خطأ.

في هذه الصفحة
  1. ما الذي يحكم الوصول إلى الشبكة المحلية؟
  2. كيف يعمل الاكتشاف فعلًا؟
  3. لماذا لا يجد التطبيق شيئًا؟
  4. كيف تشخّص المشكلة خطوة بخطوة؟
  5. كيف تصمم التجربة حول قيود لا تملكها؟
  6. ملاحظات أمنية لا تُهمل
  7. الخلاصة

تريد أن يجد تطبيقك جهازًا آخر في الغرفة نفسها: هاتفًا يستقبل ملفًا، أو جهازًا على الشبكة تريد إيقاظه، أو خادمًا محليًا في المكتب. تكتب الكود، تختبره على المحاكي فيعمل، ثم تجرّبه على جهاز حقيقي فلا يجد شيئًا — ولا رسالة خطأ واضحة تقول لماذا.

الشبكة المحلية في iOS محكومة بإذن صريح وبإعدادات في ملف الحقوق، وأغلب حالات «لا يجد أي جهاز» ليست مشكلة في منطق الاكتشاف بل في هذه الطبقة. هذا المقال عن الترتيب الصحيح: ما الذي يجب إعداده، وكيف تعمل الآلية فعلًا، وأين تفشل بصمت.

ما الذي يحكم الوصول إلى الشبكة المحلية؟

الشبكة المحلية هي مجموعة الأجهزة المتصلة بالموجّه نفسه والقادرة على مخاطبة بعضها مباشرة دون المرور بخادم خارجي. ومنذ iOS 14 صار أي اتصال بأجهزة على هذه الشبكة محكومًا بإذن مستقل تمامًا عن إذن الإنترنت العادي. السبب أن مسح الشبكة المحلية يكشف ما حولك: أجهزة المنزل، الطابعات، التلفزيون، وأحيانًا أسماء تحمل اسم صاحبها — وهذا بحد ذاته معلومة عن المستخدم.

ثلاثة أشياء يجب أن تجتمع قبل أن ينجح أي اكتشاف:

  • مفتاح `NSLocalNetworkUsageDescription` في ملف الخصائص، بنص يشرح للمستخدم سبب الطلب. غيابه يعني أن الطلب لن يظهر أصلًا.
  • الإعلان عن الخدمات التي ستبحث عنها في NSBonjourServices، بأسمائها الكاملة مثل _myservice._tcp. لن يُعاد إليك سوى ما أعلنته.
  • موافقة المستخدم على المربع الذي يظهر عند أول محاولة اتصال محلي.

النقطة الثانية هي الأكثر إرباكًا: أن تنسى إعلان خدمة يعني أنك لن تجدها أبدًا، والنظام لا يخبرك بذلك — يعيد ببساطة قائمة فارغة، تمامًا كما لو لم يكن هناك جهاز.

غياب النتائج في الشبكة المحلية ليس دليلًا على غياب الأجهزة. غالبًا هو دليل على إذن ناقص أو خدمة غير معلنة.

كيف يعمل الاكتشاف فعلًا؟

الآلية اسمها Bonjour، وهي تنفيذ آبل لمعيارَي mDNS وDNS-SD، وفكرتها بسيطة: بدل خادم مركزي يعرف من في الشبكة، يعلن كل جهاز عن نفسه ويستمع لإعلانات غيره عبر بث متعدد على الشبكة المحلية.

وللتعامل معها في الكود ثلاث خطوات:

  1. الإعلان (Publish). الجهاز الذي يقدّم الخدمة يعلن عن نوعها ومنفذها واسمها.
  2. التصفّح (Browse). الجهاز الباحث يستمع لإعلانات النوع الذي يهمه ويحصل على قائمة تتغيّر ديناميكيًا.
  3. الحلّ والاتصال (Resolve & Connect). عند اختيار خدمة يُحلّ اسمها إلى عنوان ومنفذ، ثم تفتح الاتصال.

الفارق العملي المهم أن الأسماء ليست عناوين. اسم الخدمة ثابت نسبيًا، أما العنوان فيتغيّر مع كل انضمام إلى الشبكة، ولذلك يجب أن تحلّ الاسم عند كل اتصال لا أن تخزّن IP وتعيد استخدامه لاحقًا. تخزين العنوان هو سبب متكرر لتطبيق «يعمل أول مرة ثم يتوقف».

في iOS الحديث يُنصح باستخدام NWBrowser وNWListener من إطار Network بدل NetService القديم، لأنهما يتعاملان مع IPv6 والشبكات المزدوجة بشكل أصح، ويعطيان حالات اتصال أوضح.

لماذا لا يجد التطبيق شيئًا؟

سبعة أسباب، مرتّبة بحسب تكرارها في الواقع لا بحسب أهميتها النظرية.

السببالعلامة
خدمة غير معلنة في NSBonjourServicesقائمة فارغة دائمًا
المستخدم رفض إذن الشبكة المحليةفراغ بعد ظهور المربع مرة
الشبكة تعزل العملاء (Client Isolation)يعمل بالمنزل لا بالمقهى
الجهازان على شبكتين مختلفتينأحدهما على بيانات الجوال
الجهاز الآخر نائميظهر ثم يختفي
جدار حماية يحجب المنفذيُكتشف ولا يتصل
اختبار على المحاكييعمل ثم يفشل على الجهاز

عزل العملاء هو السبب الأول للحيرة، لأنه خارج سيطرتك تمامًا: كثير من شبكات الضيوف والمقاهي والفنادق تمنع الأجهزة من رؤية بعضها عمدًا. تطبيقك سليم والشبكة ترفض، والشيء الوحيد الممكن هو رسالة واضحة للمستخدم تقترح شبكة أخرى.

الاختبار على المحاكي مضلّل بشكل خاص: المحاكي يشارك شبكة الـ Mac ولا يطبّق قيود الإذن كما يطبّقها الجهاز، فتظهر نتائج لن تتكرر عند المستخدم. أي اختبار جدّي لهذه الميزة يجري على جهازين حقيقيين.

كيف تشخّص المشكلة خطوة بخطوة؟

التشخيص هنا مختلف لأن الفشل صامت غالبًا، ولا استثناء يُلتقط ولا رمز خطأ يُقرأ. الترتيب التالي يحسم الحالة في دقائق بدل ساعة من التخمين.

  1. تأكد أن المربع ظهر أصلًا. إن لم يظهر إذن الشبكة المحلية قط، فالمشكلة في ملف الخصائص لا في الكود. راجع الإعدادات ← الخصوصية ← الشبكة المحلية وابحث عن تطبيقك؛ غيابه من القائمة يعني أنه لم يطلب الإذن يومًا.
  2. جرّب من الطرف الآخر. شغّل أداة تصفّح Bonjour على الـ Mac المتصل بالشبكة نفسها. إن رأت هي الخدمة ولم يرها تطبيقك، فالمشكلة في الإعلان أو الإذن؛ وإن لم ترها أيضًا فالمشكلة في الجهاز المعلن أو الشبكة.
  3. بدّل الشبكة. جرّب نقطة اتصال من هاتف ثالث. نجاحها الفوري يثبت أن الشبكة الأصلية تعزل عملاءها، وهذا يوفّر عليك تعديل كود سليم.
  4. سجّل الحالات لا النتائج. سجّل انتقالات حالة المتصفّح والاتصال، لا القائمة النهائية فقط، لأن الفرق بين «لم يبدأ» و«بدأ ولم يجد» يظهر في الانتقالات وحدها.
  5. اختبر الرفض عمدًا. ارفض الإذن مرة وشاهد ما يعرضه تطبيقك. كثير من التطبيقات تعرض في هذه الحالة «لا توجد أجهزة»، وهي رسالة تدفع المستخدم للبحث في المكان الخطأ تمامًا.

الخطوة الثانية هي الأسرع في الحسم عمليًا، لأنها تفصل بين طرفين اثنين في أقل من دقيقة وتوقف الجدل حول أي الجهازين المسؤول.

وثمة تفصيل أخير يخصّ الخلفية: النظام لا يبقي الاكتشاف حيًّا إلى الأبد بعد خروج التطبيق من الشاشة، والتصفّح المستمر في الخلفية ليس سلوكًا مضمونًا. صمّم على أن الاكتشاف عملية قصيرة يبدأها المستخدم وتنتهي، لا خدمة دائمة تعمل ما دام التطبيق مثبتًا.

كيف تصمم التجربة حول قيود لا تملكها؟

بما أن نصف أسباب الفشل خارج التطبيق، فالتصميم الجيد يعترف بذلك بدل أن يخفيه.

اطلب الإذن في اللحظة الصحيحة. لا عند الإقلاع، بل عند أول محاولة اكتشاف فعلية بعد فعل من المستخدم. الطلب في سياق مفهوم يُقبل أكثر بكثير من طلب بلا سبب ظاهر.

اشرح الفارق بين لا يوجد ولا أستطيع. «لم يُعثر على أجهزة» و«الإذن مرفوض» و«الشبكة تمنع الرؤية» ثلاث حالات مختلفة تحتاج ثلاثة نصوص مختلفة وثلاثة إجراءات مختلفة.

اعرض اسم الشبكة الحالية. سطر واحد يحسم أكثر أسئلة الدعم شيوعًا، لأن المستخدم يكتشف بنفسه أن الجهازين على شبكتين.

وفّر مسارًا بديلًا. رمز QR أو رمز إقران قصير يعمل حين يفشل الاكتشاف التلقائي — وهو النمط الذي تعتمد عليه تطبيقات النقل المحلي مثل loopStream حين تتعذّر الرؤية التلقائية.

تعامل مع الأجهزة النائمة كحالة عادية. الجهاز الذي يظهر ثم يختفي ليس عطلًا، وتطبيقات الإيقاظ عبر الشبكة مثل Wakivo مبنية على هذه الحقيقة تحديدًا: الجهاز غير المرئي ليس بالضرورة غائبًا.

ملاحظات أمنية لا تُهمل

الشبكة المحلية ليست منطقة موثوقة لمجرد أنها محلية، وهذا افتراض شائع وخطر.

  • أي جهاز على الشبكة يستطيع الإعلان عن أي اسم. لا شيء يمنع جهازًا من انتحال اسم خدمتك، فلا تبنِ الثقة على الاسم وحده.
  • شفّر الاتصال. TLS داخل الشبكة المحلية ليس مبالغة؛ شبكات المقاهي والمكاتب المشتركة تُقرأ بسهولة أكبر مما يُظن.
  • أضف إقرانًا صريحًا. موافقة المستخدم على جهاز بعينه — مرة واحدة، مع تذكّرها لاحقًا — أفضل من قبول أي جهاز يعلن عن النوع الصحيح.
  • لا تنشر معلومات في اسم الخدمة. الاسم مرئي لكل من على الشبكة، ووضع اسم المستخدم أو رقم الجهاز فيه تسريب صامت.

النقطة الأخيرة تُخالف كثيرًا في التطبيقات الحقيقية، لأن اسم الجهاز الافتراضي في iOS كثيرًا ما يحمل اسم صاحبه، فيصل إلى الشبكة دون أن ينتبه أحد.

مزيد عن البنية في الموبايل وأدوات المطوّر والبرمجة. وتوثيق إطار Network يغطي NWBrowser وNWListener بالتفصيل.

الخلاصة

الشبكة المحلية في iOS تحتاج إذنًا صريحًا وإعلانًا مسبقًا بأنواع الخدمات، وأغلب حالات «لا يجد شيئًا» سببها مفتاح ناقص في ملف الخصائص أو شبكة تعزل عملاءها لا خلل في كودك.

أعلن خدماتك، اطلب الإذن في سياق مفهوم، حلّ الأسماء عند كل اتصال بدل تخزين العناوين، واختبر على جهازين حقيقيين لا على المحاكي — وميّز في الواجهة بين «لا يوجد» و«لا أستطيع»، لأن المستخدم لا يملك طريقة أخرى ليعرف أيهما حدث.

أسئلة شائعة

لماذا تعود قائمة الأجهزة فارغة دائمًا؟
غالبًا لأن نوع الخدمة غير معلن في NSBonjourServices. النظام لا يخبرك بذلك، بل يعيد قائمة فارغة تمامًا كما لو لم يوجد أي جهاز على الشبكة.
لماذا يعمل الاكتشاف في المنزل ويفشل في المقهى؟
لأن كثيرًا من شبكات الضيوف تعزل العملاء عمدًا فتمنع الأجهزة من رؤية بعضها. هذا خارج سيطرة التطبيق، وأفضل ما يمكن فعله رسالة واضحة تقترح شبكة أخرى.
هل أخزّن عنوان IP للجهاز لاستخدامه لاحقًا؟
لا. الأسماء ثابتة نسبيًا والعناوين تتغيّر مع كل انضمام للشبكة، فحلّ الاسم عند كل اتصال. تخزين العنوان سبب متكرر لتطبيق يعمل أول مرة ثم يتوقف.
هل يكفي الاختبار على المحاكي؟
لا. المحاكي يشارك شبكة الـ Mac ولا يطبّق قيود الإذن كما يطبّقها الجهاز، فيعطي نتائج لن تتكرر عند المستخدم. الاختبار الجدّي يجري على جهازين حقيقيين.

المصادر

  1. Network frameworkApple Developer
  2. Bonjour overviewApple Developer
  3. loopStream: File TransferTecno Blocks
Bahaa Taha — بهاء طه

نشرته

MrBebo

محتوى تقني عربي يقدمه بهاء طه حول البرمجة، الذكاء الاصطناعي، Web2 وWeb3، تطوير التطبيقات، بناء المنتجات وأدوات المطورين.

عن المدوّنة

قراءات ذات صلة

تابع القراءة

تصفّح كل شيء