Background Fetch هي آلية في iOS توقظ التطبيق بشكل دوري في الخلفية لتحميل محتوى جديد. يحلل النظام سلوك المستخدم ويختار النوافذ المثلى للتحديث. وفقاً لـ Apple، 2026، يحصل التطبيق على 30 إلى 120 ثانية لتنفيذ العملية، وبعدها يوقف النظام أو ينهي العملية.
النقاط الرئيسية
Background Fetch هي واجهة برمجة تطبيقات iOS تسمح للتطبيق بتلقي بيانات جديدة بشكل دوري في الخلفية. تم تقديمها لأول مرة في iOS 7 مع آلية Background App Refresh. الهدف الرئيسي هو أن يكون المحتوى محدثاً بحلول الوقت الذي يفتح فيه المستخدم التطبيق، دون الحاجة لانتظار التحميل.
الإشعارات الفورية يبدأها الخادم — حيث يرسل إشارة إلى الجهاز، ويقرر النظام ما إذا كان سيوقظ التطبيق أم لا. Background Fetch يبدأ بواسطة iOS نفسه بناءً على أنماط استخدام الجهاز. الإشعارات الفورية مناسبة للرسائل العاجلة، بينما Fetch مناسب للتحديثات المجدولة للمحتوى (الأخبار، تغذية وسائل التواصل الاجتماعي).
Background Fetch هي إحدى آليات التنفيذ في الخلفية المتعددة في iOS. BGAppRefreshTask (iOS 13+) يؤدي نفس المهمة ولكن بجدولة أكثر مرونة. Background Modes (الصوت، الموقع) مخصصة للعمليات المستمرة. Silent Push هي تحديثات يبدأها الخادم. يظل Fetch مناسباً للمشاريع التي تدعم iOS 12 والإصدارات الأقدم.
iOS يستخدم خوارزمية تعلم آلي لتحديد الوقت الأمثل لاستيقاظ التطبيق. يحلل النظام متى يفتح المستخدم التطبيق عادةً، ومدة استخدامه، وعدد مرات عودته. بناءً على هذه البيانات، يحسب iOS نوافذ Background Fetch.
عندما يقرر النظام إيقاظ التطبيق، يستدعي الطريقة application(_:performFetchWithCompletionHandler:) في AppDelegate. يجب على التطبيق تحميل كمية صغيرة من البيانات الجديدة واستدعاء معالج الإكمال مع إحدى الحالات الثلاث: .newData (تم تحميل البيانات)، .noData (لا توجد بيانات جديدة) أو .failed (خطأ). تؤثر الحالة على تكرار الاستيقاظ في المستقبل.
حالة .newData تخبر النظام أن التحديث كان مفيداً — قد يزيد iOS من تكرار الاستيقاظ. .noData تعني عدم وجود بيانات — يظل التكرار كما هو أو ينخفض. .failed تشير إلى مشكلة — يقلل النظام التكرار لتوفير البطارية. يجب التركيز على الحالة الصادقة، وليس على فرض .newData.
| الحالة | المعنى | التأثير |
|---|---|---|
| .newData | تم تحميل البيانات بنجاح | قد يزيد التكرار |
| .noData | الفحص لم يعط بيانات جديدة | يبقى التكرار كما هو |
| .failed | خطأ في الشبكة أو الخادم | يقل التكرار |
لتفعيل Background Fetch، يلزم خطوتان: تفعيل الإمكانية في Xcode وتعيين الحد الأدنى للفاصل الزمني في الكود. توجد الإمكانية في Target — Signing & Capabilities — Background Modes — تفعيل خانة Background Fetch. بدون هذه الخطوة، لن يوقظ النظام التطبيق.
الطريقة UIApplication.shared.setMinimumBackgroundFetchInterval تحدد الحد الأدنى للوقت بالثواني بين استدعاءات Fetch. القيمة UIApplication.backgroundFetchIntervalMinimum (حوالي 15 دقيقة) تخبر النظام بإيقاظ التطبيق بقدر ما هو موفر للطاقة. تعيين الفاصل الزمني في application(_:didFinishLaunchingWithOptions:) هو ممارسة قياسية.
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions options: [UIApplication.LaunchOptionsKey : Any]?
)-> Bool {
UIApplication.shared.setMinimumBackgroundFetchInterval(
UIApplication.backgroundFetchIntervalMinimum
)
return true
}
عند تفعيل Background Fetch في Xcode، يقوم بتحديث Info.plist تلقائياً — يضيف المفتاح UIBackgroundModes بقيمة fetch. هذه خطوة إلزامية: بدونها لن يتلقى التطبيق استدعاء performFetchWithCompletionHandler. يمكنك التحقق من ذلك عبر P list Source أو Build Settings.
لنلق نظرة على تطبيق كامل Background Fetch لتطبيق أخبار. يشمل التطبيق تحميل البيانات، التخزين المؤقت واستدعاء معالج الإكمال. يتم تنفيذ الكود في AppDelegate — المكان الوحيد الذي يستدعي فيه النظام fetch.
func application(
_ application: UIApplication,
performFetchWithCompletionHandler handler: @escaping (UIBackgroundFetchResult) -> Void
) {
let url = URL(string: "https://api.example.com/latest")!
URLSession.shared.dataTask(with: url) { data, response, error in
guard let data = data, error == nil else {
handler(.failed)
return
}
do {
let articles = try JSONDecoder().decode([Article].self, from: data)
cacheArticles(articles)
handler(articles.isEmpty ? .noData : .newData)
} catch {
handler(.failed)
}
}.resume()
}
بعد تحميل البيانات عبر Background Fetch، يجب حفظها في التخزين المحلي — CoreData أو UserDefaults أو File Manager. عند فتح التطبيق، يجب أن تكون البيانات متاحة بالفعل. استخدم CoreData مع سياق خلفي للكتابة الآمنة متعددة الخيوط. بعد الحفظ، قم بتحديث واجهة المستخدم في الخيط الرئيسي.
func cacheArticles(_ articles: [Article]) {
let container = NSPersistentContainer(name: "AppModel")
container.performBackgroundTask { context in
articles.forEach { article in
let entity = ArticleEntity(context: context)
entity.id = Int64(article.id)
entity.title = article.title
entity.body = article.body
}
try? context.save()
}
}
للاختبار، استخدم المحاكي — اختر Debug — Simulate Background Fetch في Xcode. على الجهاز الفعلي، عليك الانتظار حتى يقرر النظام تنفيذ fetch. للتسريع، يمكنك تعيين الفاصل الزمني الأدنى إلى دقيقة واحدة، لكن النظام قد يتجاهله عندما تكون البطارية منخفضة.
Background Fetch لديها عدة قيود مهمة يجب مراعاتها عند تصميم بنية التطبيق. الأساسي هو أن النظام يتحكم بالكامل في تكرار الاستدعاءات، ولا يمكن للمطور ضمانها. حتى مع تعيين فاصل زمني أدنى، قد لا يستدعي النظام fetch لساعات.
يخصص النظام وقتاً محدوداً للتطبيق لتنفيذ المهمة — عادةً حتى 30 ثانية. إذا لم يستدعِ التطبيق معالج الإكمال خلال هذا الوقت، ينهي النظام العملية قسراً ويقلل تكرار الاستيقاظ في المستقبل. يجب أن تكون جميع طلبات الشبكة مضغوطة — لا تزيد عن 1-2 لكل استدعاء.
يراعي iOS مستوى البطارية عند جدولة Background Fetch. عندما يكون الشحن أقل من 20%، يقل تكرار الاستيقاظ. عند تفعيل وضع الطاقة المنخفضة، قد يعطل النظام التحديثات الخلفية بالكامل لجميع التطبيقات. يمكن للمستخدم أيضاً تعطيل Background App Refresh لتطبيق معين في الإعدادات.
URLSession المنطلق من Background Fetch يعمل في الوضع القياسي — بدون دعم جلسات الخلفية. للتحميلات الكبيرة، استخدم URLSession مع تهيئة خلفية. سيستمر النظام في التحميل حتى بعد انتهاء fetch، لكن لن يتم تتبع التقدم حتى الاستيقاظ التالي.
بدءاً من iOS 13، توصي Apple BGTaskScheduler كبديل لـ Background Fetch. يوفر BGTaskScheduler جدولة أكثر مرونة، نوعين من المهام (refresh و processing) وتسجيل المهام بمعرفات. يتضمن الانتقال عدة خطوات ويوصى به لجميع المشاريع الجديدة.
الخطوة الأولى — تعريف معرفات المهام في Info.plist باستخدام المفتاح BGTaskSchedulerPermittedIdentifiers. الثانية — تسجيل المهام في AppDelegate عبر BGTaskScheduler.shared.register. الثالثة — استبدال استدعاء performFetchWithCompletionHandler بمعالج الإكمال الممرر إلى register. الرابعة — استدعاء submit لجدولة المهمة.
// قبل (Background Fetch)
UIApplication.shared.setMinimumBackgroundFetchInterval(
UIApplication.backgroundFetchIntervalMinimum
)
// بعد الترحيل (BGTaskScheduler)
BGTaskScheduler.shared.register(
forTaskWithIdentifier: "com.example.refresh",
using: nil
) { task in
self.handleAppRefresh(task: task as! BGAppRefreshTask)
}
let request = BGAppRefreshTaskRequest(
identifier: "com.example.refresh"
)
request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60)
try? BGTaskScheduler.shared.submit(request)
يوفر BGTaskScheduler تحكماً أكبر: BGProcessingTask للعمليات الطويلة (حتى 10 دقائق)، شروط التنفيذ عبر requiresNetworkConnectivity و requiresExternalPower، ومعالج انتهاء الصلاحية للإنهاء المنظم. يحلل النظام أيضاً استخدام التطبيق، لكن يمكن للمطور تعيين متطلبات أكثر دقة.
إذا كان التطبيق يدعم iOS 12 والإصدارات الأقدم، يبقى Background Fetch الخيار الوحيد للتحديثات الدورية. BGTaskScheduler متاح فقط من iOS 13+. في هذه الحالة، استخدم غلافاً: تحقق من التوفر عبر if #available(iOS 13, *) واستدعِ API المناسب.
الأسئلة الشائعة
التكرار الدقيق غير موثق ويعتمد على سلوك المستخدم. يحلل النظام عدد مرات فتح المستخدم للتطبيق ويضبط التكرار وفقاً لذلك. في المتوسط، مع الاستخدام النشط، قد يتم استدعاء fetch 1–3 مرات في الساعة. مع الاستخدام النادر — 1–2 مرات في اليوم.
تحقق من ثلاثة شروط: إمكانية Background Fetch مفعلة في Xcode، تم تعيين minimumBackgroundFetchInterval، والمستخدم لم يعطل Background App Refresh للتطبيق في الإعدادات. تحقق أيضاً من أن الجهاز ليس في وضع الطاقة المنخفضة وأن مستوى البطارية أعلى من 20%.
Background Fetch هي API قديمة (iOS 7)، BGAppRefreshTask هي API جديدة (iOS 13+). توفر BGAppRefreshTask تحكماً أكبر: معالج انتهاء الصلاحية، إمكانية إعادة الجدولة والتحقق من الحالة. Background Fetch أبسط في التنفيذ لكنها أقل مرونة. توصي Apple باستخدام BGAppRefreshTask للمشاريع الجديدة.
لا يُنصح بذلك. Background Fetch محدودة بالوقت (حتى 30 ثانية). للتحميلات الكبيرة، استخدم URLSession مع تهيئة خلفية — سيستمر النظام في التحميل حتى بعد انتهاء fetch. البديل هو BGProcessingTask (iOS 13+) الذي يسمح بما يصل إلى 10 دقائق وشروط الشحن.
نعم، كل استيقاظ يستهلك طاقة لتشغيل المعالج، تهيئة مكدس الشبكة وتحميل البيانات. يحسن iOS التكرار لتقليل التأثير. مع التنفيذ الصحيح — تحميل البيانات الجديدة فقط، استدعاء سريع لمعالج الإكمال — التأثير على البطارية ضئيل.
الخلاصة
سنقوم بتطوير تطبيق جوال جاهز
تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا