Background Fetch — مکانیزم iOS که به صورت دورهای برنامه را در پسزمینه برای بارگیری محتوای تازه بیدار میکند. سیستم رفتار کاربر را تحلیل کرده و پنجرههای بهینه را برای بهروزرسانی انتخاب میکند. طبق دادههای Apple, 2026، برنامه بین 30 تا 120 ثانیه برای انجام عملیات فرصت دارد و پس از آن سیستم فرآیند را متوقف یا خاتمه میدهد.
نکات مهم
Background Fetch — API iOS است که به برنامه اجازه میدهد به صورت دورهای دادههای تازه را در پسزمینه دریافت کند. اولین بار در iOS 7 همراه با مکانیزم Background App Refresh معرفی شد. هدف اصلی این است که محتوا در لحظه باز کردن برنامه توسط کاربر بهروز باشد، بدون نیاز به انتظار برای بارگیری.
اعلانهای Push توسط سرور آغاز میشوند — سرور سیگنالی به دستگاه ارسال میکند و سیستم تصمیم میگیرد برنامه را بیدار کند یا خیر. Background Fetch توسط خود iOS بر اساس الگوهای استفاده از دستگاه آغاز میشود. Push برای پیامهای فوری مناسبتر است، Fetch — برای بهروزرسانی برنامهریزی شده محتوا (اخبار، فید شبکه اجتماعی).
Background Fetch — یکی از چندین مکانیزم اجرای پسزمینه در iOS است. BGAppRefreshTask (iOS 13+) همان وظیفه را انجام میدهد، اما با برنامهریزی انعطافپذیرتر. Background Modes (صوت، موقعیت) — برای عملیاتهای مداوم. Silent Push — بهروزرسانی آغاز شده توسط سرور. Fetch برای پروژههایی که از iOS 12 و پایینتر پشتیبانی میکنند همچنان مناسب است.
iOS از الگوریتم یادگیری ماشین برای تعیین زمان بهینه بیدار کردن برنامه استفاده میکند. سیستم تحلیل میکند که کاربر معمولاً چه زمانی برنامه را باز میکند، چه مدت از آن استفاده میکند و چند بار برمیگردد. بر اساس این دادهها، iOS پنجرههایی را برای Background Fetch محاسبه میکند.
هنگامی که سیستم تصمیم به بیدار کردن برنامه میگیرد، متد application(_:performFetchWithCompletionHandler:) را در AppDelegate فراخوانی میکند. برنامه باید حداقل مقدار داده جدید را بارگیری کرده و completion handler را با یکی از سه وضعیت فراخوانی کند: .newData (داده بارگیری شد)، .noData (داده جدیدی وجود ندارد) یا .failed (خطا). وضعیت بر دفعات بیدار شدن در آینده تأثیر میگذارد.
وضعیت .newData به سیستم اطلاع میدهد که بهروزرسانی مفید بوده — iOS ممکن است دفعات بیدار شدن را افزایش دهد. .noData میگوید دادهای وجود ندارد — دفعات ثابت میماند یا کاهش مییابد. .failed نشاندهنده مشکل است — سیستم دفعات را کاهش میدهد تا باتری هدر نرود. تأکید باید روی وضعیت صادقانه باشد، نه .newData اجباری.
| وضعیت | معنی | تأثیر |
|---|---|---|
| .newData | داده با موفقیت بارگیری شد | دفعات ممکن است افزایش یابد |
| .noData | بررسی داده جدیدی نداشت | دفعات ثابت میماند |
| .failed | خطای شبکه یا سرور | دفعات کاهش مییابد |
برای فعال کردن Background Fetch باید دو مرحله انجام دهید: capability را در Xcode فعال کنید و حداقل فاصله را در کد تنظیم کنید. Capability در 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 را برای یک برنامه خبری بررسی میکنیم. اجرا شامل بارگیری داده، ذخیره در حافظه پنهان و فراخوانی completion handler است. کد در 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()
}
}
برای تست از Simulator استفاده کنید — در Xcode گزینه Debug — Simulate Background Fetch را انتخاب کنید. در دستگاه فیزیکی باید منتظر بمانید تا سیستم تصمیم به اجرای fetch بگیرد. برای تسریع میتوانید حداقل فاصله را روی 1 دقیقه تنظیم کنید، اما سیستم ممکن است همچنان آن را در صورت کم بودن باتری نادیده بگیرد.
Background Fetch محدودیتهایی دارد که در طراحی معماری برنامه باید در نظر گرفته شوند. نکته اصلی — سیستم کاملاً دفعات فراخوانی را کنترل میکند و توسعهدهنده نمیتواند آن را تضمین کند. حتی با تنظیم حداقل فاصله، سیستم ممکن است fetch را ساعتها فراخوانی نکند.
سیستم به برنامه زمان محدودی برای اجرای وظیفه اختصاص میدهد — معمولاً تا 30 ثانیه. اگر برنامه در این مدت completion handler را فراخوانی نکند، سیستم به اجبار فرآیند را خاتمه داده و دفعات بیدار شدن در آینده را کاهش میدهد. تمام درخواستهای شبکه باید فشرده باشند — حداکثر 1–2 در هر فراخوانی.
iOS سطح شارژ باتری را در برنامهریزی Background Fetch در نظر میگیرد. هنگامی که سطح شارژ زیر 20٪ است، دفعات بیدار شدن کاهش مییابد. در حالت Low Power Mode، سیستم ممکن است بهطور کامل بهروزرسانیهای پسزمینه را برای همه برنامهها غیرفعال کند. کاربر همچنین میتواند Background App Refresh را برای یک برنامه خاص در تنظیمات غیرفعال کند.
URLSession که از Background Fetch راهاندازی میشود در حالت استاندارد کار میکند — بدون پشتیبانی از جلسات پسزمینه. برای بارگیریهای بزرگ از URLSession با background configuration استفاده کنید. سیستم بارگیری را حتی پس از پایان 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، expiration handler برای پایان نرم. سیستم همچنین استفاده از برنامه را تحلیل میکند، اما توسعهدهنده میتواند الزامات دقیقتری تعیین کند.
اگر برنامه از iOS 12 و پایینتر پشتیبانی میکند، Background Fetch تنها گزینه برای بهروزرسانی دورهای باقی میماند. BGTaskScheduler فقط از iOS 13+ در دسترس است. در این حالت از یک wrapper استفاده کنید: دسترسی BGTaskScheduler را از طریق if #available(iOS 13, *) بررسی کرده و API مربوطه را فراخوانی کنید.
سوالات متداول
دفعات دقیق مستند نشده و به رفتار کاربر بستگی دارد. سیستم تحلیل میکند که کاربر چند وقت یک بار برنامه را باز میکند و دفعات را متناسباً تنظیم میکند. به طور متوسط با استفاده فعال، fetch ممکن است 1–3 بار در ساعت فراخوانی شود. با استفاده نادر — 1–2 بار در روز.
سه شرط را بررسی کنید: Background Fetch capability در Xcode فعال است، minimumBackgroundFetchInterval تنظیم شده است، و کاربر Background App Refresh را برای برنامه در تنظیمات غیرفعال نکرده است. همچنین بررسی کنید که دستگاه در Low Power Mode نباشد و سطح باتری بالای 20٪ باشد.
Background Fetch — API قدیمی (iOS 7)، BGAppRefreshTask — API جدید (iOS 13+). BGAppRefreshTask کنترل بیشتری فراهم میکند: expiration handler، امکان برنامهریزی مجدد و بررسی وضعیت. Background Fetch در پیادهسازی سادهتر اما انعطافپذیرتر است. Apple استفاده از BGAppRefreshTask را برای پروژههای جدید توصیه میکند.
توصیه نمیشود. Background Fetch از نظر زمان محدود است (تا 30 ثانیه). برای بارگیریهای بزرگ از URLSession با background configuration استفاده کنید — سیستم بارگیری را حتی پس از پایان fetch ادامه خواهد داد. جایگزین — BGProcessingTask (iOS 13+) که تا 10 دقیقه زمان و شرایط شارژ را فراهم میکند.
بله، هر بیدار شدن برای روشن کردن پردازنده، راهاندازی پشته شبکه و بارگیری داده انرژی مصرف میکند. iOS بهینهسازی میکند دفعات را برای به حداقل رساندن تأثیر. با پیادهسازی صحیح — بارگیری فقط دادههای جدید، فراخوانی سریع completion handler — تأثیر روی باتری حداقل است.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید