Background Task: مفاهیم کلیدی، ثبت وظایف و اجرا در پس‌زمینه

نویسنده: IT Sectr منتشر شده: 2026-03-27 زمان مطالعه: 10 دقیقه

Background Task — مکانیزم iOS است که به برنامه اجازه می‌دهد عملیات شروع‌شده را پس از انتقال به حالت پس‌زمینه تکمیل کند. سیستم زمان محدودی (تا ۳۰ ثانیه) برای اجرای وظیفه اختصاص می‌دهد و پس از آن برنامه به‌اجبار متوقف می‌شود. به گفته Apple, 2026، استفاده از expiration handler یک الزام اجباری برای تکمیل صحیح وظیفه پس‌زمینه است.

نکات اصلی

  • Background Task — مکانیزم iOS برای تکمیل عملیات پس از رفتن برنامه به پس‌زمینه.
  • beginBackgroundTask — روش کلیدی UIApplication برای ثبت وظیفه پس‌زمینه.
  • Expiration handler — بلوک کدی که سیستم هنگام اتمام زمان اختصاص‌یافته فراخوانی می‌کند.
  • محدودیت ۳۰ ثانیه — زمان استاندارد برای اجرا، تمدید از طریق Background Modes.
  • UIApplication.shared.endBackgroundTask — فراخوانی اجباری برای تکمیل صحیح وظیفه.

Background Task در iOS چیست؟

Background Task یک مکانیزم نرم‌افزاری iOS است که به برنامه اجازه می‌دهد زمان اجرا را پس از انتقال به حالت پس‌زمینه افزایش دهد. وقتی کاربر برنامه را می‌بندد، سیستم UIApplicationDelegate.applicationDidEnterBackground را فراخوانی می‌کند. اگر در این لحظه یک عملیات حیاتی (ذخیره داده، ارسال درخواست) در حال اجرا باشد، برنامه می‌تواند از طریق beginBackgroundTask زمان اضافی درخواست کند.

چرا به Background Tasks نیاز داریم

بدون استفاده از Background Task، برنامه پس از ۳–۵ ثانیه از رفتن به پس‌زمینه به‌اجبار متوقف می‌شود. تمام عملیات ناتمام قطع می‌شوند: داده‌ها ذخیره نمی‌شوند، درخواست‌های شبکه قطع می‌شوند، حالت‌ها از دست می‌روند. Background Task تا ۳۰ ثانیه به برنامه برای تکمیل صحیح این عملیات فرصت می‌دهد.

  • ذخیره وضعیت — نوشتن داده در CoreData، UserDefaults یا سیستم فایل.
  • تکمیل درخواست‌های شبکه — منتظر ماندن برای پاسخ سرور و پردازش نتیجه.
  • ارسال تحلیل — انتقال رویدادها به سرور تحلیل قبل از تعلیق.
  • پاکسازی منابع — بستن توصیفگرهای فایل، آزادسازی حافظه.
  • ذخیره‌سازی موقت — نوشتن نتایج میانی برای بازیابی در راه‌اندازی بعدی.

تاریخچه و تکامل

beginBackgroundTask در iOS 4.0 — اولین نسخه‌ای که از چندوظیفگی پشتیبانی می‌کرد — ظاهر شد. قبل از iOS 4، برنامه با فشردن دکمه Home کاملاً بسته می‌شد. از iOS 7 به بعد، Background Fetch و URLSession background configuration معرفی شدند. از iOS 13، Apple برای پروژه‌های جدید BGTaskScheduler را توصیه می‌کند، اما beginBackgroundTask برای عملیات کوتاه‌مدت همچنان کاربردی است.

beginBackgroundTask چگونه کار می‌کند: چرخه حیات

beginBackgroundTask متدی از UIApplication است که وظیفه را ثبت می‌کند و یک شناسه یکتا UIBackgroundTaskIdentifier برمی‌گرداند. سیستم تایمر اجرای پس‌زمینه را افزایش می‌دهد. پس از اتمام زمان، expiration handler فراخوانی می‌شود و سپس برنامه باید برای تکمیل صحیح endBackgroundTask(identifier:) را فراخوانی کند.

فرآیند گام‌به‌گام اجرا

گام ۱ — برنامه اعلان didEnterBackground را دریافت می‌کند. گام ۲ — beginBackgroundTask(expirationHandler:) فراخوانی می‌شود. گام ۳ — عملیات حیاتی (ذخیره، درخواست شبکه) اجرا می‌شود. گام ۴ — پس از اتمام، endBackgroundTask(identifier:) فراخوانی می‌شود. اگر عملیات در ۳۰ ثانیه تمام نشود — سیستم expiration handler را فراخوانی می‌کند و برنامه باید وظیفه را فوراً پایان دهد.

swift
var backgroundTaskID: UIBackgroundTaskIdentifier = .invalid

func startBackgroundTask() {
    backgroundTaskID = UIApplication.shared.beginBackgroundTask {
        // Expiration handler
        UIApplication.shared.endBackgroundTask(backgroundTaskID)
        backgroundTaskID = .invalid
    }
}

func finishBackgroundTask() {
    UIApplication.shared.endBackgroundTask(backgroundTaskID)
    backgroundTaskID = .invalid
}

UIApplication.shared.backgroundTimeRemaining

ویژگی backgroundTimeRemaining تعداد ثانیه‌های باقی‌مانده تا پایان اجباری وظیفه پس‌زمینه را برمی‌گرداند. مقدار در زمان واقعی کاهش می‌یابد. اگر برنامه در پس‌زمینه نباشد — DBL_MAX برمی‌گرداند. از این ویژگی برای تطبیق رفتار استفاده کنید: وقتی کمتر از ۵ ثانیه باقی مانده، عملیات طولانی را قطع کرده و پیشرفت را ذخیره کنید.

وظایف متعدد

برنامه می‌تواند چندین Background Task را همزمان ثبت کند. هر وظیفه شناسه خود را دریافت می‌کند. زمان کل اجرا جمع می‌شود — اگر ۳ وظیفه ثبت شده باشد، برنامه می‌تواند تا ۹۰ ثانیه زمان بگیرد. با این حال، سیستم ممکن است در صورت اتمام منابع یا تجاوز از حد باتری، برنامه را زودتر پایان دهد.

Expiration handler: پردازش اجباری اتمام

Expiration handler بلوک کدی است که سیستم هنگام اتمام زمان اختصاص‌یافته برای وظیفه پس‌زمینه فراخوانی می‌کند. وجود expiration handler یک الزام اجباری Apple است. بدون آن، برنامه ممکن است توسط سیستم به‌اجبار پایان یابد و داده‌ها از دست بروند.

چه چیزی باید در expiration handler باشد

Expiration handler باید حداقل اقدامات را برای ذخیره وضعیت برنامه انجام دهد: داده‌های جاری را در حافظه پایدار ذخیره کند، endBackgroundTask را با شناسه مربوطه فراخوانی کند و شناسه را روی .invalid تنظیم کند. در داخل expiration handler شروع عملیات طولانی جدید ممنوع است — زمان اجرا به ۱–۲ ثانیه محدود می‌شود.

swift
func handleExpiration() {
    // پیشرفت اجرا را ذخیره می‌کنیم
    saveProgressToUserDefaults()

    // درخواست‌های شبکه فعال را لغو می‌کنیم
    currentTask?.cancel()

    // Background Task را پایان می‌دهیم
    UIApplication.shared.endBackgroundTask(backgroundTaskID)
    backgroundTaskID = .invalid
}

// ثبت با expiration handler
backgroundTaskID = UIApplication.shared.beginBackgroundTask(
    withName: "SaveDocument",
    expirationHandler: handleExpiration
)

خطاهای کار با expiration handler

رایج‌ترین خطا فراخوانی نکردن endBackgroundTask در داخل expiration handler است. در این صورت سیستم همچنان وظیفه را فعال در نظر می‌گیرد، برنامه به حالت Suspended نمی‌رود و باتری تخلیه می‌شود. خطای دوم شروع عملیات طولانی در داخل expiration handler است. سیستم ممکن است قبل از اتمام آن‌ها برنامه را پایان دهد و داده‌ها از دست بروند.

بررسی زمان باقی‌مانده

در expiration handler زمان اجرا بحرانی کم است — معمولاً کمتر از ۱ ثانیه. بنابراین در داخل handler نمی‌توان: محاسبات پیچیده، درخواست‌های شبکه، نوشتن حجم زیاد داده در CoreData انجام داد. فقط عملیات اتمی: نوشتن یک کلید در UserDefaults، تنظیم پرچم وضعیت، فراخوانی endBackgroundTask.

نمونه کدهای Background Task در Swift

بیایید پیاده‌سازی کامل Background Task برای ذخیره سند هنگام رفتن برنامه به پس‌زمینه را بررسی کنیم. مثال شامل ثبت وظیفه، اجرای عملیات با بررسی زمان باقی‌مانده و تکمیل صحیح از طریق endBackgroundTask است.

ذخیره سند با پیشرفت

هنگام رفتن به پس‌زمینه، برنامه ذخیره یک سند بزرگ را آغاز می‌کند. Background Task تا ۳۰ ثانیه برای عملیات فرصت می‌دهد. اگر زمان تمام شود — expiration handler نتایج میانی را ذخیره می‌کند. پس از اتمام ذخیره، endBackgroundTask برای آزادسازی منابع فراخوانی می‌شود.

swift
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
    }
}

ارسال داده به سرور

درخواست‌های شبکه در پس‌زمینه نیاز به توجه ویژه دارند — expiration handler ممکن است درخواست را قبل از دریافت پاسخ قطع کند. از URLSession با dataTask استفاده کنید و قبل از ارسال backgroundTimeRemaining را بررسی کنید. اگر کمتر از ۵ ثانیه باقی مانده — ارسال را تا بیدار شدن بعدی برنامه به تعویق بیندازید.

swift
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 را ردیابی کنید. اگر مقدار از آستانه (۱۰ ثانیه) پایین‌تر رفت، عملیات جاری را قطع کرده و ذخیره نتایج میانی را شروع کنید. این امکان را می‌دهد که قبل از فراخوانی اجباری expiration handler کار را به‌درستی پایان دهید.

بهترین روش‌های استفاده از Background Task

Background Task مکانیزم قدرتمندی است، اما استفاده نادرست از آن منجر به مشکلات باتری و عملکرد می‌شود. رعایت توصیه‌های Apple و روش‌های تأییدشده جامعه به جلوگیری از خطاهای رایج و تضمین عملکرد پایدار برنامه کمک می‌کند.

کمینه‌سازی زمان اجرا

Background Task را هر چه سریع‌تر پایان دهید. هر ثانیه اجرای پس‌زمینه انرژی باتری مصرف می‌کند. زمان بهینه — کمتر از ۵ ثانیه. اگر عملیات بیشتر طول می‌کشد — استفاده از BGTaskScheduler یا Background Modes را در نظر بگیرید. بدون نیاز واقعی، وظیفه را به‌طور مصنوعی از طریق فراخوانی‌های beginBackgroundTask طولانی نکنید.

استفاده صحیح از شناسه‌ها

UIBackgroundTaskIdentifier را به عنوان ویژگی کلاس یا ساختار ذخیره کنید. هرگز آن را به عنوان متغیر سراسری منتقل نکنید — این منجر به تداخل در وظایف متعدد می‌شود. پس از فراخوانی endBackgroundTask، شناسه را روی .invalid تنظیم کنید تا از تکمیل مضاعف جلوگیری شود.

تست Background Task

در Xcode Simulator برنامه را از طریق دکمه Home (Command + Shift + H) به پس‌زمینه ببرید. از Debug — Simulate Background Fetch برای تست بیدارشدن پس‌زمینه استفاده کنید. برای شبیه‌سازی اتمام زمان، متغیر محیطی BACKGROUND_TASK_SIMULATE_EXPIRATION = YES را تنظیم کنید — expiration handler پس از ۵ ثانیه فراخوانی می‌شود.

swift
// بررسی زمان باقی‌مانده قبل از شروع عملیات
let remaining = UIApplication.shared.backgroundTimeRemaining
guard remaining > 10.0 else {
    // زمان کافی نیست — وظیفه را به تعویق بینداز
    scheduleForNextLaunch()
    return
}

// اجرای عملیات با کنترل زمان
backgroundTaskID = UIApplication.shared.beginBackgroundTask {
    saveProgress()
    self.endBackgroundTask()
}

اجتناب از چرخه‌های retain

Expiration handler self را می‌گیرد — اگر backgroundTaskID به عنوان ویژگی همان شیء ذخیره شود، می‌تواند چرخه retain ایجاد کند. از [weak self] در بسته استفاده کنید یا شناسه را جداگانه ذخیره کنید. چرخه retain منجر به نشت حافظه می‌شود — شیء تا پایان برنامه آزاد نخواهد شد.

Background Task در مقابل BGTaskScheduler: مقایسه رویکردها

با عرضه iOS 13، Apple BGTaskScheduler را معرفی کرد — جایگزین مدرن API قدیمی Background Task. هر دو مکانیزم وظایف مشابهی را حل می‌کنند، اما BGTaskScheduler کنترل و انعطاف‌پذیری بیشتری فراهم می‌کند. درک تفاوت‌ها به انتخاب ابزار مناسب برای سناریوی خاص کمک می‌کند.

ویژگیBackground TaskBGTaskScheduler
نسخه iOS4.0+13.0+
حداکثر زمان۳۰ ثانیه۳۰ ثانیه / ۱۰ دقیقه (processing)
شروعdidEnterBackgroundبرنامه‌ریزی + سیستم
تضمین اجرافقط هنگام رفتن به پس‌زمینههر زمان مناسب برای سیستم
Expiration handlerبله، اجباریبله، از طریق task.expirationHandler
اینترنتنیاز در زمان شروعاز طریق requiresNetworkConnectivity
شارژنیاز ندارداختیاری برای processing

چه زمانی از Background Task استفاده کنیم

beginBackgroundTask برای عملیات کوتاه‌مدتی مناسب است که باید بلافاصله هنگام رفتن به پس‌زمینه انجام شوند: ذخیره وضعیت، تکمیل درخواست شبکه، ذخیره‌سازی داده. API ساده است و نیاز به پیکربندی Info.plist یا ثبت شناسه‌ها ندارد. ایده‌آل برای عملیاتی که کمتر از ۱۰ ثانیه طول می‌کشند.

چه زمانی از BGTaskScheduler استفاده کنیم

BGTaskScheduler برای وظایفی مناسب است که می‌توانند در هر زمان مناسب انجام شوند: همگام‌سازی دوره‌ای، پاکسازی حافظه نهان، به‌روزرسانی ویجت‌ها. سیستم خود زمان بهینه را با توجه به رفتار کاربر و وضعیت باتری انتخاب می‌کند. برای عملیات طولانی (تا ۱۰ دقیقه) از BGProcessingTask استفاده کنید.

استفاده مشترک

هر دو API را می‌توان در یک برنامه استفاده کرد. Background Task — برای عملیات فوری هنگام رفتن به پس‌زمینه (ذخیره پیش‌نویس). BGTaskScheduler — برای به‌روزرسانی‌های برنامه‌ریزی‌شده (همگام‌سازی هر ۶ ساعت). تقسیم مسئولیت امکان ذخیره صحیح داده‌ها و سرویس‌دهی پس‌زمینه با مصرف بهینه انرژی را فراهم می‌کند.

سوالات متداول

آیا می‌توان beginBackgroundTask را خارج از didEnterBackground فراخوانی کرد؟

بله، beginBackgroundTask را می‌توان در هر لحظه از کار برنامه فراخوانی کرد. با این حال، تخصیص زمان سیستم فقط پس از رفتن به پس‌زمینه شروع می‌شود. اگر برنامه در پیش‌زمینه است، فراخوانی beginBackgroundTask اثری ندارد — backgroundTimeRemaining DBL_MAX برمی‌گرداند و وظیفه هنگام رفتن به پس‌زمینه فعال می‌شود.

اگر endBackgroundTask فراخوانی نشود چه اتفاقی می‌افتد؟

اگر endBackgroundTask فراخوانی نشود، سیستم همچنان برنامه را در پس‌زمینه فعال در نظر می‌گیرد. پس از ۳۰ ثانیه expiration handler فراخوانی می‌شود، اما اگر در آن هم endBackgroundTask نباشد — برنامه در حافظه باقی می‌ماند و باتری مصرف می‌کند. در iOS 13+ سیستم چنین برنامه‌ای را پس از ۳ دقیقه به‌اجبار پایان می‌دهد.

چگونه زمان Background Task را بیش از ۳۰ ثانیه افزایش دهیم؟

زمان استاندارد ۳۰ ثانیه است. افزایش آن فقط از طریق Background Modes امکان‌پذیر است: Audio (پخش)، Location (موقعیت‌یابی)، Bluetooth (BLE). یا از طریق BGProcessingTask (iOS 13+) — تا ۱۰ دقیقه با شرایط شارژ و Wi-Fi. beginBackgroundTask به خودی خود راهی برای افزایش محدودیت فراهم نمی‌کند.

آیا Background Task در iPad کار می‌کند؟

بله، iPadOS به‌طور کامل از beginBackgroundTask با همان محدودیت‌های iOS پشتیبانی می‌کند. در iPad با Stage Manager، برنامه می‌تواند بیشتر در حافظه بماند — سیستم به دلیل RAM بیشتر، برنامه‌ها را کمتر تعلیق می‌کند. اما محدودیت ۳۰ ثانیه برای وظیفه پس‌زمینه باقی می‌ماند.

چگونه Background Task را در دستگاه واقعی اشکال‌زدایی کنیم؟

دستگاه را به Xcode متصل کنید، برنامه را اجرا کنید، آن را به حداقل برسانید — لاگ‌های سیستم در کنسول ظاهر می‌شوند. از sysdiagnose برای جمع‌آوری لاگ‌های دقیق استفاده کنید: sysdiagnose را از دستگاه فراخوانی کنید (Volume Up + Down + Power). در Xcode Debug Navigator فعالیت وظایف پس‌زمینه را ردیابی کنید.

خلاصه

  • Background Task — مکانیزم iOS برای تکمیل عملیات پس از رفتن به پس‌زمینه، قابل دسترس از iOS 4.0.
  • beginBackgroundTask — متد UIApplication که وظیفه را ثبت کرده و شناسه‌ای برای تکمیل آن برمی‌گرداند.
  • Expiration handler — بلوک کد اجباری که توسط سیستم پس از اتمام محدودیت ۳۰ ثانیه فراخوانی می‌شود.
  • endBackgroundTask — فراخوانی اجباری برای تکمیل صحیح وظیفه؛ بدون آن برنامه در حافظه باقی می‌ماند.
  • BGTaskScheduler — جایگزین مدرن (iOS 13+) با برنامه‌ریزی، دو نوع وظیفه و شرایط اجرا.
  • backgroundTimeRemaining — ویژگی برای بررسی زمان باقی‌مانده و تطبیق رفتار وظیفه.
  • برای عملیات کوتاه‌مدت فوری از Background Task و برای به‌روزرسانی‌های برنامه‌ریزی‌شده پس‌زمینه در پروژه‌های جدید از BGTaskScheduler استفاده کنید.

ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد

IT Sectr از سال 2017 برنامه‌های iOS و Android را برای استارتاپ‌ها و کسب‌وکارها ایجاد می‌کند. ما به شما مشاوره می‌دهیم و بهترین راه‌حل را پیشنهاد خواهیم کرد.

بحث درباره پروژه

همچنین بخوانید