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

المهام الخلفية في iOS: ما يُسمح به وما يُقتل

لا توجد صلاحية تشغّل ما تريد في الخلفية — بل قائمة محددة لكل عنصر فيها غرض معلن، وكل ما خارجها يتوقف بلا إشعار.

Bahaa Taha — بهاء طهMrBebo
تسجيل صوتي طويل، وهو بالضبط نوع العمل الذي يقاطعه النظام
تسجيل صوتي طويل، وهو بالضبط نوع العمل الذي يقاطعه النظام

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

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

في هذه الصفحة
  1. ما المسموح به فعلًا؟
  2. ما الذي يُقتل ولا يمكن إنقاذه؟
  3. كيف تُعلن عنها وتفعّلها؟
  4. لماذا لا تُنفَّذ المهمة في الوقت المطلوب؟
  5. تصميم يحتمل الإنهاء
  6. كيف تراقب ما يحدث فعلًا؟
  7. ما الذي يراه المستخدم؟
  8. الخلاصة

يسأل المطوّرون الجدد على iOS سؤالًا واحدًا متكررًا: «كيف أجعل الكود يعمل باستمرار في الخلفية؟» والجواب أن النظام لا يسمح بذلك، ولا توجد صلاحية تمنح استثناءً. لكن هذا ليس منعًا كاملًا — بل قائمة محددة من الحالات المسموح بها، وكل ما هو خارجها يُقتل.

المهام الخلفية هي العمل الذي ينفّذه التطبيق وهو غير معروض على الشاشة، وفي iOS تُنفَّذ عبر مجموعة آليات معرَّفة مسبقًا لكل واحدة غرض معلن وشروط تفعيل، والنظام يمنحها موارد بحسب ذلك الغرض لا بحسب حاجة تطبيقك. معرفة القائمة تحسم أغلب أسئلة التصميم قبل كتابة سطر.

ما المسموح به فعلًا؟

قائمة المهام الخلفية المسموح بها أقصر مما يظن كثيرون.

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

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

ما الذي يُقتل ولا يمكن إنقاذه؟

ثلاث حالات من المهام الخلفية يظنها المطوّرون قابلة للحل وهي ليست كذلك.

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

المؤقتات. المؤقت لا يعمل والتطبيق معلّق. أي منطق يعتمد على مرور الوقت يجب أن يُحسب من طابع زمني محفوظ عند العودة، لا أن يُراكم بالعدّ.

الاتصال الدائم. مقبس ويب مفتوح ينقطع عند التعليق. البديل هو الإشعار الصامت الذي يوقظ التطبيق ليجلب ما تغيّر، وهو غير مضمون التوقيت.

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

كيف تُعلن عنها وتفعّلها؟

تفعيل المهام الخلفية ثلاث خطوات، وترتيبها يهم.

  1. فعّل القدرة المطلوبة في إعدادات الهدف، فتُضاف إلى ملف الحقوق. بلا ذلك لا تعمل الآلية ولا تظهر رسالة خطأ واضحة.
  2. سجّل معرّف المهمة عند الإقلاع لكل مهمة مجدولة، وقبل انتهاء تهيئة التطبيق. التسجيل المتأخر يُهمل بصمت.
  3. اطلب الجدولة عند لحظة مناسبة — عند دخول الخلفية عادة — وأعد الطلب في كل مرة، لأن الجدولة لا تتكرر تلقائيًا بعد التنفيذ.

الخطوة الثالثة سبب متكرر لمهمة «عملت مرة واحدة ثم توقفت». الجدولة عملية لمرة واحدة، وإعادة الطلب من داخل المهمة نفسها قبل انتهائها هي النمط الصحيح.

لماذا لا تُنفَّذ المهمة في الوقت المطلوب؟

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

ثلاث نتائج عملية:

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

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

تصميم يحتمل الإنهاء

أربع قواعد تجعل المهام الخلفية قابلة للاستئناف بدل أن تضيع.

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

اجعل كل خطوة قابلة للتكرار بلا ضرر. بعد الإنهاء لا تعرف هل اكتملت آخر خطوة، فإعادتها يجب ألا تُنتج ازدواجًا. معرّف عملية من جهتك يتجاهله الخادم إن تكرر يحلّ هذا الصنف كله.

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

سجّل نيّة المستخدم كسجل مستقل عن التقدّم. عند الإقلاع التالي تستطيع أن تسأل: ما الذي طلبه المستخدم ولم يكتمل؟ وبلا ذلك، العملية المنقطعة لم توجد أصلًا.

القاعدة الرابعة هي الفرق بين تطبيق يقول «انقطع التفريغ — هل نكمل؟» وتطبيق يفقد العمل صامتًا، وهذا فرق يظهر مباشرة في التقييمات. تطبيقات التسجيل والتفريغ مثل TapMemo تعتمد على هذا تحديدًا لأن التسجيل الطويل هو بالضبط ما يقاطعه النظام.

كيف تراقب ما يحدث فعلًا؟

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

أربع أدوات عملية:

  • سجّل عبر نظام السجلات الموحّد لا بالطباعة. مخرجات الطباعة من تنفيذ قصير في الخلفية تضيع، بينما سجلّ النظام يبقى ويمكن قراءته لاحقًا من تطبيق Console موصولًا بالجهاز.
  • سجّل التوقيت لا الحدث فقط. ما يهم هو متى نُفِّذت المهمة وكم استغرقت، لأن الفجوات هي المعلومة الحقيقية. سطر واحد عند البداية وآخر عند النهاية يكفي.
  • احفظ آخر تنفيذ ناجح في مكان يقرأه المستخدم. «آخر تحديث: أمس 9:20» في شاشة الإعدادات يحوّل سؤال دعم غامضًا إلى إجابة فورية.
  • راقب في الإنتاج لا في التطوير فقط. جهازك يعمل بنمط استخدام مختلف تمامًا عن أجهزة المستخدمين، وميزانية التنفيذ عندك أسخى لأنك تفتح التطبيق كل يوم.

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

ما الذي يراه المستخدم؟

نقطة تُهمَل وهي نصف المسألة.

قل صراحة إن العمل لن يستمر عند الخروج حين يكون ذلك صحيحًا. الصمت هنا ليس حيادًا بل وعد ضمني بأن العمل مستمر.

اعرض تقدّمًا بوحدة حقيقية، «3 من 12 دقيقة» لا مؤشرًا دائريًا، لأن قرار المستخدم بالبقاء على الشاشة يعتمد على معرفة كم بقي.

ميّز «لم يكتمل» عن «فشل». حالتان مختلفتان تحتاجان إجراءين مختلفين، ودمجهما في رسالة واحدة يعلّم المستخدم تجاهلها.

لا تعرض اكتمالًا قبل وجود الملف على القرص. شريط يصل إلى مئة بالمئة قبل النقل النهائي وعد لم يُوفَ به بعد.

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

مزيد في الموبايل وأدوات المطوّر والبرمجة، وتوثيق BackgroundTasks يغطي التسجيل والجدولة بالتفصيل.

الخلاصة

المهام الخلفية في iOS قائمة محددة من الآليات لا صلاحية عامة، وما هو خارج القائمة — الحساب الطويل، والمؤقتات، والاتصال الدائم — يتوقف عند التعليق بلا إشعار.

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

أسئلة شائعة

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

المصادر

  1. BackgroundTasksApple Developer
  2. Downloading files in the backgroundApple Developer
  3. TapMemo: AI Voice RecorderTecno Blocks
Bahaa Taha — بهاء طه

نشرته

MrBebo

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

عن المدوّنة

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

تابع القراءة

تصفّح كل شيء