Background Task — tətbiqin fon rejiminə keçdikdən sonra başladığı əməliyyatı tamamlamağa imkan verən iOS mexanizmidir. Sistem tapşırığın yerinə yetirilməsi üçün məhdud vaxt (30 saniyəyə qədər) ayırır, bundan sonra tətbiq məcburi olaraq dayandırılır. Apple, 2026-ya görə, expiration handler-dən istifadə fon tapşırığının düzgün tamamlanması üçün məcburi tələbdir.
Əsas məqamlar
Background Task — tətbiqə fon rejiminə keçdikdən sonra icra müddətini uzatmağa imkan verən proqram mexanizmidir. İstifadəçi tətbiqi bağladıqda, sistem UIApplicationDelegate.applicationDidEnterBackground-ı çağırır. Əgər bu anda kritik əməliyyat (məlumatların saxlanması, sorğunun göndərilməsi) yerinə yetirilirsə, tətbiq beginBackgroundTask vasitəsilə əlavə vaxt tələb edə bilər.
Background Task istifadə etmədən, tətbiq fona keçdikdən 3–5 saniyə sonra məcburi dayandırılır. Bütün tamamlanmamış əməliyyatlar kəsilir: məlumatlar saxlanmır, şəbəkə sorğuları pozulur, vəziyyətlər itirilir. Background Task tətbiqə bu əməliyyatları düzgün tamamlamaq üçün 30 saniyəyə qədər vaxt verir.
beginBackgroundTask iOS 4.0-da — çox tapşırıqlılığı dəstəkləyən ilk buraxılışda ortaya çıxdı. iOS 4-dən əvvəl tətbiq Home düyməsi basıldıqda tamamilə bağlanırdı. iOS 7-dən etibarən Background Fetch və URLSession background configuration meydana çıxdı. iOS 13-dən başlayaraq, Apple yeni layihələr üçün BGTaskScheduler-ı tövsiyə edir, lakin beginBackgroundTask qısamüddətli əməliyyatlar üçün aktuallığını qoruyur.
beginBackgroundTask — tapşırığı qeydiyyatdan keçirən və unikal UIBackgroundTaskIdentifier identifikatoru qaytaran UIApplication metodudur. Sistem fon icra müddətini artırır. Vaxt bitdikdə expiration handler çağırılır, bundan sonra tətbiq düzgün tamamlama üçün endBackgroundTask(identifier:)-ı çağırmalıdır.
Addım 1 — tətbiq didEnterBackground bildirişini alır. Addım 2 — beginBackgroundTask(expirationHandler:) çağırılır. Addım 3 — kritik əməliyyat (saxlama, şəbəkə sorğusu) yerinə yetirilir. Addım 4 — tamamlandıqda endBackgroundTask(identifier:) çağırılır. Əgər əməliyyat 30 saniyə ərzində tamamlanmazsa — sistem expiration handler-ı çağırır və tətbiq tapşırığı dərhal bitirməlidir.
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
}
backgroundTimeRemaining xüsusiyyəti fon tapşırığının məcburi dayandırılmasına qədər qalan saniyələrin sayını qaytarır. Dəyər real vaxtda azalır. Əgər tətbiq fonda deyilsə — DBL_MAX qaytarır. Davranışı uyğunlaşdırmaq üçün bu xüsusiyyətdən istifadə edin: 5 saniyədən az qaldıqda uzunmüddətli əməliyyatları dayandırın və irəliləyişi qeyd edin.
Tətbiq eyni anda bir neçə Background Task qeydiyyatdan keçirə bilər. Hər tapşırıq öz identifikatorunu alır. Ümumi icra müddəti toplanır — 3 tapşırıq qeydiyyatdan keçirilərsə, tətbiq 90 saniyəyə qədər vaxt ala bilər. Lakin resurslar tükənərsə və ya batareya limiti aşılırsa, sistem tətbiqi daha tez dayandıra bilər.
Expiration handler — fon tapşırığı üçün ayrılan vaxt bitdikdə sistem tərəfindən çağırılan kod blokudur. Expiration handler-in mövcudluğu Apple-ın məcburi tələbidir. Olmadan tətbiq sistem tərəfindən məcburi dayandırıla bilər və məlumatlar itirilə bilər.
Expiration handler tətbiqin vəziyyətini qorumaq üçün minimal hərəkətlər etməlidir: cari məlumatları davamlı yaddaşda saxlamaq, müvafiq identifikatorla endBackgroundTask-ı çağırmaq və identifikatoru .invalid-ə təyin etmək. Expiration handler daxilində yeni uzunmüddətli əməliyyatlar başlatmaq qadağandır — icra müddəti 1–2 saniyə ilə məhdudlaşır.
func handleExpiration() {
// İcra irəliləyişini saxlayırıq
saveProgressToUserDefaults()
// Aktiv şəbəkə sorğularını ləğv edirik
currentTask?.cancel()
// Background Task-ı bitiririk
UIApplication.shared.endBackgroundTask(backgroundTaskID)
backgroundTaskID = .invalid
}
// Expiration handler ilə qeydiyyat
backgroundTaskID = UIApplication.shared.beginBackgroundTask(
withName: "SaveDocument",
expirationHandler: handleExpiration
)
Ən çox yayılmış səhv expiration handler daxilində endBackgroundTask-ı çağırmamaqdır. Bu halda sistem tapşırığı aktiv hesab etməyə davam edir, tətbiq Suspended vəziyyətinə keçmir və batareya boşalır. İkinci səhv expiration handler daxilində uzunmüddətli əməliyyatları başlatmaqdır. Sistem onlar bitməmiş tətbiqi dayandıra bilər və məlumatlar itirilər.
Expiration handler-də icra müddəti kritik dərəcədə qısadır — adətən 1 saniyədən az. Buna görə handler daxilində yerinə yetirilməməlidir: mürəkkəb hesablamalar, şəbəkə sorğuları, CoreData-ya böyük həcmli məlumatların yazılması. Yalnız atomik əməliyyatlar: UserDefaults-da bir açarın yazılması, vəziyyət bayrağının təyin edilməsi, endBackgroundTask çağırışı.
Tətbiq fona keçdikdə sənədin saxlanması üçün Background Task-in tam tətbiqini nəzərdən keçirək. Nümunə tapşırığın qeydiyyatını, qalan vaxtın yoxlanılması ilə əməliyyatın icrasını və endBackgroundTask vasitəsilə düzgün tamamlamanı əhatə edir.
Fona keçdikdə tətbiq böyük sənədin saxlanmasını başladır. Background Task əməliyyat üçün 30 saniyəyə qədər vaxt verir. Vaxt bitərsə — expiration handler aralıq nəticələri saxlayır. Saxlama tamamlandıqdan sonra resursları boşaltmaq üçün endBackgroundTask çağırılır.
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
}
}
Fonda şəbəkə sorğuları xüsusi diqqət tələb edir — expiration handler cavab alınmazdan əvvəl sorğunu kəsə bilər. URLSession-dan dataTask ilə istifadə edin və göndərmədən əvvəl backgroundTimeRemaining-i yoxlayın. 5 saniyədən az qalıbsa — göndərməni tətbiqin növbəti oyanmasına qədər təxirə salın.
func sendCriticalData(data: Data) {
backgroundTaskID = UIApplication.shared.beginBackgroundTask {
// Təkrar göndərmə üçün məlumatları saxlayırıq
saveForRetry(data)
self.endBackgroundTask()
}
let task = URLSession.shared.dataTask(with: request) { _, _, error in
if error != nil {
saveForRetry(data)
}
self.endBackgroundTask()
}
task.resume()
}
Uzunmüddətli əməliyyatlar üçün UIApplication.shared.backgroundTimeRemaining-i izləyin. Dəyər həddən (10 saniyə) aşağı düşərsə, cari əməliyyatı dayandırın və aralıq nəticələrin saxlanmasını başladın. Bu, expiration handler-in məcburi çağırışından əvvəl işi düzgün tamamlamağa imkan verir.
Background Task — güclü mexanizmdir, lakin onun düzgün istifadə edilməməsi batareya və performans problemlərinə səbəb olur. Apple-ın tövsiyələrinə və icma tərəfindən təsdiqlənmiş təcrübələrə riayət etmək tipik səhvlərdən qaçmağa və tətbiqin sabit işini təmin etməyə kömək edir.
Background Task-ı mümkün qədər tez tamamlayın. Fon icrasının hər saniyəsi batareya enerjisini sərf edir. Optimal vaxt — 5 saniyədən az. Əməliyyat daha uzun çəkirsə — BGTaskScheduler və ya Background Modes istifadəsini nəzərdən keçirin. Həqiqi ehtiyac olmadan beginBackgroundTask çağırışları ilə tapşırığı süni şəkildə uzatmayın.
UIBackgroundTaskIdentifier-ı sinif və ya strukturun xüsusiyyəti kimi saxlayın. Onu heç vaxt qlobal dəyişən kimi ötürməyin — bu, çoxsaylı tapşırıqlar zamanı konfliktlərə səbəb olur. İkiqat tamamlamanın qarşısını almaq üçün endBackgroundTask çağırışından sonra identifikatoru .invalid-ə təyin edin.
Xcode Simulator-da tətbiqi Home düyməsi (Command + Shift + H) ilə fona keçirin. Fon oyanmasını test etmək üçün Debug — Simulate Background Fetch istifadə edin. Vaxtın bitməsini simulyasiya etmək üçün BACKGROUND_TASK_SIMULATE_EXPIRATION = YES mühit dəyişənini təyin edin — expiration handler 5 saniyədən sonra çağırılacaq.
// Əməliyyata başlamazdan əvvəl qalan vaxtın yoxlanılması
let remaining = UIApplication.shared.backgroundTimeRemaining
guard remaining > 10.0 else {
// Kifayət qədər vaxt yoxdur — tapşırığı təxirə sal
scheduleForNextLaunch()
return
}
// Vaxt nəzarəti ilə əməliyyatın icrası
backgroundTaskID = UIApplication.shared.beginBackgroundTask {
saveProgress()
self.endBackgroundTask()
}
Expiration handler self-i tutur — bu, backgroundTaskID eyni obyektin xüsusiyyəti kimi saxlanılırsa, retain cycle yarada bilər. Bağlamada [weak self] istifadə edin və ya identifikatoru ayrıca saxlayın. Retain cycle yaddaş sızmasına səbəb olur — obyekt tətbiq bitənə qədər azad edilməyəcək.
iOS 13-ün buraxılması ilə Apple köhnə Background Task API-nin müasir əvəzedicisi olan BGTaskScheduler-ı təqdim etdi. Hər iki mexanizm oxşar tapşırıqları həll edir, lakin BGTaskScheduler daha çox nəzarət və çeviklik təmin edir. Fərqləri anlamaq konkret ssenari üçün düzgün aləti seçməyə kömək edəcək.
| Xüsusiyyət | Background Task | BGTaskScheduler |
|---|---|---|
| iOS versiyası | 4.0+ | 13.0+ |
| Maks. vaxt | 30 saniyə | 30 s / 10 dəq (processing) |
| Başlatma | didEnterBackground | Planlaşdırma + sistem |
| İcra zəmanəti | Yalnız fona keçdikdə | Sistem üçün əlverişli istənilən vaxt |
| Expiration handler | Bəli, məcburi | Bəli, task.expirationHandler vasitəsilə |
| İnternet | Başlatma zamanı tələb olunur | requiresNetworkConnectivity vasitəsilə mövcuddur |
| Şarj | Tələb olunmur | Processing üçün isteğe bağlı |
beginBackgroundTask fona keçdikdə dərhal yerinə yetirilməli olan qısamüddətli əməliyyatlar üçün uyğundur: vəziyyətin saxlanması, şəbəkə sorğusunun tamamlanması, məlumatların keşlənməsi. API sadədir və Info.plist konfiqurasiyası və ya identifikatorların qeydiyyatını tələb etmir. 10 saniyədən az çəkən əməliyyatlar üçün idealdır.
BGTaskScheduler istənilən əlverişli vaxtda yerinə yetirilə bilən tapşırıqlar üçün uyğundur: dövri sinxronizasiya, keşin təmizlənməsi, vidjetlərin yenilənməsi. Sistem istifadəçinin davranışını və batareya vəziyyətini nəzərə alaraq optimal vaxtı özü seçir. Uzunmüddətli əməliyyatlar (10 dəqiqəyə qədər) üçün BGProcessingTask istifadə edin.
Hər iki API eyni tətbiqdə istifadə edilə bilər. Background Task — fona keçdikdə dərhal əməliyyatlar üçün (qaralamanın saxlanması). BGTaskScheduler — planlı yeniləmələr üçün (hər 6 saatdan bir sinxronizasiya). Məsuliyyətin bölünməsi məlumatların düzgün saxlanmasını və enerji effektiv fon xidmətini təmin etməyə imkan verir.
Tez-tez verilən suallar
Bəli, beginBackgroundTask tətbiqin istənilən anında çağırıla bilər. Lakin sistem vaxt ayırması yalnız fona keçdikdən sonra başlayacaq. Əgər tətbiq ön plandadırsa, beginBackgroundTask çağırışının effekti olmur — backgroundTimeRemaining DBL_MAX qaytarır, tapşırıq isə fona keçdikdə aktivləşəcək.
Əgər endBackgroundTask çağırılmasa, sistem tətbiqi fonda aktiv hesab etməyə davam edir. 30 saniyədən sonra expiration handler çağırılacaq, lakin orada da endBackgroundTask yoxdursa — tətbiq yaddaşda qalaraq batareyanı boşaldır. iOS 13+-da sistem belə tətbiqi 3 dəqiqədən sonra məcburi dayandırır.
Standart vaxt 30 saniyədir. Onu yalnız Background Modes vasitəsilə artırmaq olar: Audio (oxutma), Location (geolokasiya), Bluetooth (BLE). Və ya BGProcessingTask (iOS 13+) — şarj və Wi-Fi şərti ilə 10 dəqiqəyə qədər. beginBackgroundTask özlüyündə limiti artırmaq üçün heç bir yol təmin etmir.
Bəli, iPadOS beginBackgroundTask-ı iOS ilə eyni məhdudiyyətlərlə tam dəstəkləyir. Stage Manager olan iPad-də tətbiq daha uzun müddət yaddaşda qala bilər — sistem daha çox RAM səbəbindən tətbiqləri daha az dayandırır. Lakin fon tapşırığı üçün 30 saniyə limiti qalır.
Cihazı Xcode-a qoşun, tətbiqi işə salın, onu minimuma endirin — konsolda sistem jurnalları görünəcək. Ətraflı jurnalları toplamaq üçün sysdiagnose istifadə edin: cihazdan sysdiagnose-ı məcburi çağırın (Volume Up + Down + Power). Xcode Debug Navigator-da fon tapşırıqlarının aktivliyini izləyin.
Xülasə
Açar təslim mobil tətbiq hazırlayacağıq
IT Sectr 2017-ci ildən startaplar və bizneslər üçün iOS və Android tətbiqləri yaradır. Sizə məsləhət verəcəyik və ən yaxşı həlli təklif edəcəyik.
Həm də oxuyun