Background Task هي آلية في iOS تسمح للتطبيق بإكمال عملية بعد الانتقال إلى الخلفية. يخصص النظام وقتاً محدوداً (حتى 30 ثانية) لتنفيذ المهمة، وبعد ذلك يتم تعليق التطبيق قسراً. وفقاً لشركة Apple، 2026، فإن استخدام معالج انتهاء الوقت هو متطلب إلزامي لإكمال المهمة في الخلفية بشكل صحيح.
الخلاصة
Background Task هي آلية برمجية في iOS تسمح للتطبيق بتمديد وقت التنفيذ بعد الانتقال إلى الخلفية. عندما يقلل المستخدم التطبيق، يستدعي النظام UIApplicationDelegate.applicationDidEnterBackground. إذا كانت هناك عملية حرجة قيد التنفيذ في تلك اللحظة (حفظ البيانات، إرسال طلب)، يمكن للتطبيق طلب وقت إضافي عبر beginBackgroundTask.
بدون استخدام Background Task، يتم تعليق التطبيق قسراً خلال 3–5 ثوانٍ بعد الانتقال إلى الخلفية. تنقطع جميع العمليات غير المكتملة: لا يتم حفظ البيانات، تُلغى طلبات الشبكة، تُفقد الحالات. تمنح Background Task التطبيق حتى 30 ثانية لإكمال هذه العمليات بشكل صحيح.
ظهر beginBackgroundTask في iOS 4.0 — أول إصدار يدعم تعدد المهام. قبل iOS 4، كان التطبيق يُنهى بالكامل عند الضغط على زر الصفحة الرئيسية. قدم iOS 7 Background Fetch وتكوين URLSession في الخلفية. ابتداءً من iOS 13، توصي Apple باستخدام BGTaskScheduler للمشاريع الجديدة، لكن beginBackgroundTask يظل مناسباً للعمليات قصيرة المدى.
beginBackgroundTask هي طريقة UIApplication تسجل مهمة وتعيد معرفاً فريداً UIBackgroundTaskIdentifier. يزيد النظام مؤقت التنفيذ في الخلفية. عند انتهاء الوقت، يُستدعى معالج انتهاء الوقت، وبعد ذلك يجب على التطبيق استدعاء endBackgroundTask(identifier:) لإكمال المهمة بشكل صحيح.
الخطوة 1 — يتلقى التطبيق إشعار didEnterBackground. الخطوة 2 — يُستدعى beginBackgroundTask(expirationHandler:). الخطوة 3 — تُنفذ العملية الحرجة (حفظ، طلب شبكة). الخطوة 4 — عند الاكتمال، يُستدعى endBackgroundTask(identifier:). إذا لم تكتمل العملية خلال 30 ثانية — يستدعي النظام معالج انتهاء الوقت، ويجب على التطبيق إنهاء المهمة فوراً.
var backgroundTaskID: UIBackgroundTaskIdentifier = .invalid
func startBackgroundTask() {
backgroundTaskID = UIApplication.shared.beginBackgroundTask {
// معالج انتهاء الوقت
UIApplication.shared.endBackgroundTask(backgroundTaskID)
backgroundTaskID = .invalid
}
}
func finishBackgroundTask() {
UIApplication.shared.endBackgroundTask(backgroundTaskID)
backgroundTaskID = .invalid
}
الخاصية backgroundTimeRemaining تُرجع عدد الثواني المتبقية قبل إنهاء المهمة في الخلفية قسراً. تنخفض القيمة في الوقت الفعلي. إذا لم يكن التطبيق في الخلفية — تُرجع DBL_MAX. استخدم هذه الخاصية لتكييف السلوك: عندما يقل الوقت عن 5 ثوانٍ، قاطع العمليات الطويلة واحفظ التقدم.
يمكن للتطبيق تسجيل عدة Background Tasks في وقت واحد. تحصل كل مهمة على معرفها الخاص. الوقت الإجمالي للتنفيذ تراكمي — إذا تم تسجيل 3 مهام، يمكن للتطبيق الحصول على حتى 90 ثانية. ومع ذلك، قد ينهي النظام التطبيق مبكراً إذا استنفدت الموارد أو تجاوز حد البطارية.
معالج انتهاء الوقت هو كتلة برمجية يستدعيها النظام عند انتهاء الوقت المخصص للمهمة في الخلفية. وجود معالج انتهاء الوقت هو متطلب إلزامي من Apple. بدونه، قد يُنهى التطبيق قسراً بواسطة النظام وقد تُفقد البيانات.
يجب أن يقوم معالج انتهاء الوقت بإجراءات دنيا لحفظ حالة التطبيق: حفظ البيانات الحالية في تخزين دائم، استدعاء endBackgroundTask بالمعرف المناسب، وتعيين المعرف إلى .invalid. داخل معالج انتهاء الوقت، يُمنع بدء عمليات جديدة طويلة — وقت التنفيذ محدود بـ 1–2 ثانية.
func handleExpiration() {
// جارٍ حفظ تقدم التنفيذ
saveProgressToUserDefaults()
// جارٍ إلغاء طلبات الشبكة النشطة
currentTask?.cancel()
// جارٍ إنهاء Background Task
UIApplication.shared.endBackgroundTask(backgroundTaskID)
backgroundTaskID = .invalid
}
// التسجيل مع معالج انتهاء الوقت
backgroundTaskID = UIApplication.shared.beginBackgroundTask(
withName: "SaveDocument",
expirationHandler: handleExpiration
)
الخطأ الأكثر شيوعاً هو عدم استدعاء endBackgroundTask داخل معالج انتهاء الوقت. في هذه الحالة، يستمر النظام في اعتبار المهمة نشطة، لا ينتقل التطبيق إلى الحالة المعلقة، وتُستنزف البطارية. الخطأ الثاني هو بدء عمليات طويلة داخل معالج انتهاء الوقت. قد ينهي النظام التطبيق قبل اكتمالها، وسيتم فقدان البيانات.
في معالج انتهاء الوقت، وقت التنفيذ محدود بشكل حرج — عادة أقل من ثانية واحدة. لذلك، لا يمكن داخل المعالج تنفيذ: حسابات معقدة، طلبات شبكة، كتابة كميات كبيرة من البيانات إلى CoreData. فقط عمليات ذرية: كتابة مفتاح واحد في UserDefaults، تعيين علامة حالة، استدعاء endBackgroundTask.
دعنا نستعرض تطبيقاً كاملاً لـ Background Task لحفظ مستند عندما ينتقل التطبيق إلى الخلفية. يتضمن المثال تسجيل المهمة، تنفيذ العملية مع التحقق من الوقت المتبقي، والإكمال الصحيح عبر endBackgroundTask.
عند الانتقال إلى الخلفية، يبدأ التطبيق حفظ مستند كبير. توفر Background Task حتى 30 ثانية للعملية. إذا نفد الوقت — يحفظ معالج انتهاء الوقت النتائج الوسيطة. بعد اكتمال الحفظ، يُستدعى endBackgroundTask لتحرير الموارد.
class DocumentManager {
private var backgroundTaskID: UIBackgroundTaskIdentifier = .invalid
func saveDocumentInBackground(document: Document) {
backgroundTaskID = UIApplication.shared.beginBackgroundTask {
self.saveProgress(document)
self.endBackgroundTask()
}
DispatchQueue.global().async {
document.save()
self.endBackgroundTask()
}
}
private func endBackgroundTask() {
UIApplication.shared.endBackgroundTask(backgroundTaskID)
backgroundTaskID = .invalid
}
}
طلبات الشبكة في الخلفية تتطلب اهتماماً خاصاً — قد يقطع معالج انتهاء الوقت الطلب قبل تلقي الرد. استخدم URLSession مع dataTask وتحقق من backgroundTimeRemaining قبل الإرسال. إذا بقي أقل من 5 ثوانٍ — أرجئ الإرسال حتى استيقاظ التطبيق التالي.
func sendCriticalData(data: Data) {
backgroundTaskID = UIApplication.shared.beginBackgroundTask {
// جارٍ حفظ البيانات لإعادة الإرسال
saveForRetry(data)
self.endBackgroundTask()
}
let task = URLSession.shared.dataTask(with: request) { _, _, error in
if error != nil {
saveForRetry(data)
}
self.endBackgroundTask()
}
task.resume()
}
للعمليات الطويلة، راقب UIApplication.shared.backgroundTimeRemaining. إذا انخفضت القيمة عن حد معين (10 ثوانٍ)، قاطع العملية الحالية وابدأ في حفظ النتائج الوسيطة. هذا يسمح بالإكمال الصحيح قبل استدعاء معالج انتهاء الوقت قسراً.
Background Task آلية قوية، لكن استخدامها غير الصحيح يؤدي إلى مشاكل في البطارية والأداء. اتباع توصيات Apple والممارسات المثبتة من المجتمع سيساعد في تجنب الأخطاء الشائعة وضمان تشغيل مستقر للتطبيق.
أكمل Background Task في أسرع وقت ممكن. كل ثانية من التنفيذ في الخلفية تستهلك طاقة البطارية. الوقت الأمثل — أقل من 5 ثوانٍ. إذا استغرقت العملية وقتاً أطول — فكر في استخدام BGTaskScheduler أو Background Modes. لا تمدد المهمة بشكل مصطنع عبر استدعاءات beginBackgroundTask دون حاجة حقيقية.
خزّن UIBackgroundTaskIdentifier كخاصية للفئة أو البنية. لا تمرره كمتغير عام — فهذا يؤدي إلى تعارضات مع مهام متعددة. عيّن المعرف إلى .invalid بعد استدعاء endBackgroundTask لمنع الإنهاء المزدوج.
في محاكي Xcode، حوّل التطبيق إلى الخلفية عبر زر الصفحة الرئيسية (Command + Shift + H). استخدم Debug — Simulate Background Fetch لاختبار الاستيقاظ في الخلفية. لمحاكاة انتهاء الوقت، عيّن متغير البيئة BACKGROUND_TASK_SIMULATE_EXPIRATION = YES — سيتم استدعاء معالج انتهاء الوقت خلال 5 ثوانٍ.
// التحقق من الوقت المتبقي قبل بدء العملية
let remaining = UIApplication.shared.backgroundTimeRemaining
guard remaining > 10.0 else {
// وقت غير كافٍ — تأجيل المهمة
scheduleForNextLaunch()
return
}
// تنفيذ العملية مع التحكم بالوقت
backgroundTaskID = UIApplication.shared.beginBackgroundTask {
saveProgress()
self.endBackgroundTask()
}
معالج انتهاء الوقت يلتقط self — هذا يمكن أن يخلق دورة احتفاظ إذا تم تخزين backgroundTaskID كخاصية لنفس الكائن. استخدم [weak self] في الإغلاق أو خزّن المعرف بشكل منفصل. دورة الاحتفاظ تؤدي إلى تسرب ذاكري — لن يتم تحرير الكائن حتى إنهاء التطبيق.
مع إصدار iOS 13، قدمت Apple BGTaskScheduler — بديلاً حديثاً لواجهة Background Task القديمة. كلا الآليتين تحلان مهاماً متشابهة، لكن BGTaskScheduler يوفر مزيداً من التحكم والمرونة. فهم الاختلافات سيساعد في اختيار الأداة المناسبة لسيناريو محدد.
| الخاصية | Background Task | BGTaskScheduler |
|---|---|---|
| إصدار iOS | 4.0+ | 13.0+ |
| الوقت الأقصى | 30 ثانية | 30 ث / 10 د (processing) |
| البدء | didEnterBackground | جدولة + النظام |
| ضمان التنفيذ | عند الانتقال للخلفية فقط | في أي وقت مناسب للنظام |
| معالج انتهاء الوقت | نعم، إلزامي | نعم، عبر task.expirationHandler |
| الإنترنت | مطلوب عند البدء | متاح عبر requiresNetworkConnectivity |
| الشحن | غير مطلوب | اختياري لـ processing |
beginBackgroundTask مناسب للعمليات قصيرة المدى التي يجب تنفيذها فوراً عند الانتقال إلى الخلفية: حفظ الحالة، إكمال طلب شبكة، تخزين بيانات مؤقتة. الواجهة بسيطة ولا تتطلب تكوين Info.plist أو تسجيل معرفات. مثالي للعمليات التي تستغرق أقل من 10 ثوانٍ.
BGTaskScheduler مناسب للمهام التي يمكن تنفيذها في أي وقت مناسب: المزامنة الدورية، تنظيف ذاكرة التخزين المؤقت، تحديث الأدوات. يختار النظام نفسه الوقت الأمثل مع مراعاة سلوك المستخدم وحالة البطارية. للعمليات الطويلة (حتى 10 دقائق)، استخدم BGProcessingTask.
يمكن استخدام كلتا الواجهتين في نفس التطبيق. Background Task — للعمليات الفورية عند الانتقال إلى الخلفية (حفظ مسودة). BGTaskScheduler — للتحديثات المجدولة (المزامنة كل 6 ساعات). فصل المسؤوليات يضمن الحفظ الصحيح للبيانات وصيانة خلفية موفرة للطاقة.
الأسئلة الشائعة
نعم، يمكن استدعاء beginBackgroundTask في أي وقت أثناء تنفيذ التطبيق. ومع ذلك، سيبدأ تخصيص وقت النظام فقط بعد الانتقال إلى الخلفية. إذا كان التطبيق في المقدمة، فإن استدعاء beginBackgroundTask ليس له تأثير — backgroundTimeRemaining يُرجع DBL_MAX، وسيتم تنشيط المهمة عند الانتقال إلى الخلفية.
إذا لم يتم استدعاء endBackgroundTask، يستمر النظام في اعتبار التطبيق نشطاً في الخلفية. بعد 30 ثانية، سيتم استدعاء معالج انتهاء الوقت، ولكن إذا كان يفتقر أيضاً إلى endBackgroundTask — يبقى التطبيق في الذاكرة، مستنزفاً البطارية. في iOS 13+، ينهي النظام هذا التطبيق قسراً بعد 3 دقائق.
الوقت القياسي هو 30 ثانية. يمكن تمديده فقط عبر Background Modes: الصوت (التشغيل)، الموقع (تحديد الموقع الجغرافي)، Bluetooth (BLE). أو عبر BGProcessingTask (iOS 13+) — حتى 10 دقائق مع الشحن وWi-Fi. beginBackgroundTask بحد ذاته لا يوفر طريقة لزيادة الحد.
نعم، iPadOS يدعم beginBackgroundTask بالكامل بنفس القيود الموجودة في iOS. على iPad مع Stage Manager، قد يبقى التطبيق في الذاكرة لفترة أطول — يعلق النظام التطبيقات بشكل أقل تكراراً بسبب ذاكرة الوصول العشوائي الأكبر. لكن حد 30 ثانية للمهام في الخلفية يظل قائماً.
قم بتوصيل الجهاز بـ Xcode، شغل التطبيق، صغّره — ستظهر سجلات النظام في وحدة التحكم. استخدم sysdiagnose لجمع سجلات مفصلة: فعّل sysdiagnose قسراً من الجهاز (رفع الصوت + خفض الصوت + الطاقة). في متصفح التصحيح Xcode Debug Navigator، راقب نشاط المهام في الخلفية.
الملخص
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا