Background Task: кључни појмови, регистрација задатака и извршавање у позадини

Аутор: IT Sectr Објављено: 2026-03-27 Време читања: 10 мин

Background Task — механизам iOS-а који омогућава апликацији да заврши започету операцију након преласка у позадински режим. Систем додељује ограничено време (до 30 секунди) за извршавање задатка, након чега се апликација принудно зауставља. Према Apple, 2026, употреба expiration handler-а је обавезан услов за правилно завршавање позадинског задатка.

Главне тачке

  • Background Task — механизам iOS-а за завршавање операција након одласка апликације у позадину.
  • beginBackgroundTask — кључни метод UIApplication-а за регистрацију позадинског задатка.
  • Expiration handler — блок кода који систем позива када истекне додељено време.
  • Ограничење 30 секунди — стандардно време за извршавање, продужење кроз Background Modes.
  • UIApplication.shared.endBackgroundTask — обавезан позив за правилно завршавање задатка.

Шта је Background Task у iOS-у?

Background Task је програмски механизам iOS-а који омогућава апликацији да продужи време извршавања након преласка у позадински режим. Када корисник минимизује апликацију, систем позива UIApplicationDelegate.applicationDidEnterBackground. Ако се у том тренутку извршава критична операција (чување података, слање захтева), апликација може затражити додатно време путем beginBackgroundTask.

Чему служе Background Tasks

Без коришћења Background Task-а, апликација се принудно зауставља након 3–5 секунди од одласка у позадину. Све незавршене операције се прекидају: подаци се не чувају, мрежни захтеви се прекидају, стања се губе. Background Task даје апликацији до 30 секунди за правилно завршавање ових операција.

  • Чување стања — упис података у 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:) ради правилног завршетка.

Корачни процес извршавања

Корак 1 — апликација прима обавештење didEnterBackground. Корак 2 — позива се beginBackgroundTask(expirationHandler:). Корак 3 — извршава се критична операција (чување, мрежни захтев). Корак 4 — по завршетку се позива endBackgroundTask(identifier:). Ако се операција не заврши за 30 секунди — систем позива 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. Користите ово својство за прилагођавање понашања: када остане мање од 5 секунди, прекините дуготрајне операције и сачувајте напредак.

Вишеструки задаци

Апликација може регистровати неколико Background Task-ова истовремено. Сваки задатак добија сопствени идентификатор. Укупно време извршавања се сабира — ако су регистрована 3 задатка, апликација може добити до 90 секунди. Међутим, систем може раније завршити апликацију ако су ресурси исцрпљени или је прекорачена граница батерије.

Expiration handler: обавезна обрада завршетка

Expiration handler је блок кода који систем позива када истекне додељено време за позадински задатак. Постојање expiration handler-а је обавезан услов компаније Apple. Без њега, апликација може бити принудно завршена од стране система, а подаци могу бити изгубљени.

Шта треба да буде у expiration handler-у

Expiration handler треба да изврши минималне радње за чување стања апликације: сачува тренутне податке у трајном складишту, позове endBackgroundTask са одговарајућим идентификатором и постави идентификатор на .invalid. Унутар expiration handler-а забрањено је покретање нових дуготрајних операција — време извршавања је ограничено на 1–2 секунде.

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-у време извршавања је критично кратко — обично мање од 1 секунде. Стога се унутар handler-а не могу извршавати: сложена израчунавања, мрежни захтеви, упис великих количина података у CoreData. Само атомске операције: упис једног кључа у UserDefaults, постављање статусне заставице, позив endBackgroundTask.

Примери кода Background Task у Swift-у

Размотримо потпуну имплементацију Background Task-а за чување документа при одласку апликације у позадину. Пример укључује регистрацију задатка, извршавање операције са провером преосталог времена и правилан завршетак путем endBackgroundTask.

Чување документа са напретком

При одласку у позадину, апликација покреће чување великог документа. Background Task даје до 30 секунди за операцију. Ако време истекне — 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 пре слања. Ако је остало мање од 5 секунди — одложите слање до следећег буђења апликације.

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. Ако вредност падне испод прага (10 секунди), прекините тренутну операцију и покрените чување међурезултата. Ово омогућава правилан завршетак рада пре принудног позива expiration handler-а.

Најбоље праксе коришћења Background Task-а

Background Task је моћан механизам, али његово неправилно коришћење доводи до проблема са батеријом и перформансама. Поштовање препорука Apple-а и проверених пракси заједнице помаже у избегавању типичних грешака и обезбеђивању стабилног рада апликације.

Минимизација времена извршавања

Завршите Background Task што је пре могуће. Свака секунда позадинског извршавања троши енергију батерије. Оптимално време — мање од 5 секунди. Ако операција траје дуже — размотрите коришћење BGTaskScheduler-а или Background Modes-а. Не продужавајте задатак вештачки путем beginBackgroundTask позива без стварне потребе.

Правилно коришћење идентификатора

Чувајте UIBackgroundTaskIdentifier као својство класе или структуре. Никада га не прослеђујте као глобалну променљиву — то доводи до конфликата код вишеструких задатака. Поставите идентификатор на .invalid након позива endBackgroundTask да бисте спречили двоструко завршавање.

Тестирање Background Task-а

У Xcode Simulator-у пребаците апликацију у позадину путем дугмета Home (Command + Shift + H). Користите Debug — Simulate Background Fetch за тестирање позадинског буђења. За симулацију истека времена поставите променљиву окружења BACKGROUND_TASK_SIMULATE_EXPIRATION = YES — expiration handler ће бити позван након 5 секунди.

swift
// Провера преосталог времена пре почетка операције
let remaining = UIApplication.shared.backgroundTimeRemaining
guard remaining > 10.0 else {
    // Недовољно времена — одложи задатак
    scheduleForNextLaunch()
    return
}

// Извршавање операције са контролом времена
backgroundTaskID = UIApplication.shared.beginBackgroundTask {
    saveProgress()
    self.endBackgroundTask()
}

Избегавајте retain cycle-ове

Expiration handler хвата self — то може створити retain cycle ако се backgroundTaskID чува као својство истог објекта. Користите [weak self] у затварању или чувајте идентификатор одвојено. Retain cycle доводи до цурења меморије — објекат неће бити ослобођен до завршетка апликације.

Background Task vs BGTaskScheduler: поређење приступа

Са изласком iOS-а 13, Apple је представио BGTaskScheduler — модерну замену за стари Background Task API. Оба механизма решавају сличне задатке, али BGTaskScheduler пружа више контроле и флексибилности. Разумевање разлика помаже у одабиру правог алата за конкретан сценариј.

КарактеристикаBackground TaskBGTaskScheduler
Верзија iOS4.0+13.0+
Макс. време30 секунди30 с / 10 мин (processing)
ИницијацијаdidEnterBackgroundПланирање + систем
Гаранција извршењаСамо при преласку у позадинуУ било које време погодно за систем
Expiration handlerДа, обавезанДа, путем task.expirationHandler
ИнтернетПотребан при покретањуДоступан путем requiresNetworkConnectivity
ПуњењеНије потребноОпционо за processing

Када користити Background Task

beginBackgroundTask је погодан за краткорочне операције које треба извршити одмах при одласку у позадину: чување стања, завршавање мрежног захтева, кеширање података. API је једноставан и не захтева конфигурацију Info.plist-а или регистрацију идентификатора. Идеалан за операције које трају мање од 10 секунди.

Када користити BGTaskScheduler

BGTaskScheduler је погодан за задатке који се могу извршити у било које погодно време: периодична синхронизација, чишћење кеша, ажурирање виџета. Систем сам бира оптимално време узимајући у обзир понашање корисника и стање батерије. За дуготрајне операције (до 10 минута) користите BGProcessingTask.

Заједничко коришћење

Оба API-ја се могу користити у једној апликацији. Background Task — за хитне операције при одласку у позадину (чување нацрта). BGTaskScheduler — за планирана ажурирања (синхронизација сваких 6 сати). Подела одговорности омогућава гарантовање правилног чувања података и енергетски ефикасног позадинског сервиса.

Често постављана питања

Може ли се beginBackgroundTask позвати ван didEnterBackground?

Да, beginBackgroundTask се може позвати у било ком тренутку рада апликације. Међутим, системско додељивање времена почиње тек након преласка у позадину. Ако је апликација у предњем плану, позив beginBackgroundTask нема ефекта — backgroundTimeRemaining враћа DBL_MAX, а задатак ће бити активиран при одласку у позадину.

Шта се дешава ако се не позове endBackgroundTask?

Ако се не позове endBackgroundTask, систем наставља да сматра апликацију активном у позадини. Након 30 секунди биће позван expiration handler, али ако ни у њему нема endBackgroundTask — апликација остаје у меморији, трошећи батерију. У iOS 13+ систем принудно завршава такву апликацију након 3 минута.

Како повећати време Background Task-а преко 30 секунди?

Стандардно време је 30 секунди. Повећати га се може само кроз Background Modes: Audio (репродукција), Location (геолокација), Bluetooth (BLE). Или путем BGProcessingTask (iOS 13+) — до 10 минута уз услов пуњења и Wi-Fi-ја. beginBackgroundTask сам по себи не пружа начин за повећање лимита.

Да ли Background Task ради на iPad-у?

Да, iPadOS у потпуности подржава beginBackgroundTask са истим ограничењима као iOS. На iPad-у са Stage Manager-ом, апликација може остати у меморији дуже — систем ређе зауставља апликације због веће количине RAM-а. Али лимит од 30 секунди за позадински задатак остаје.

Како отклонити грешке Background Task-а на стварном уређају?

Повежите уређај са Xcode-ом, покрените апликацију, минимизујте је — у конзоли ће се појавити системски дневници. Користите sysdiagnose за прикупљање детаљних дневника: принудно покрените sysdiagnose са уређаја (Volume Up + Down + Power). У Xcode Debug Navigator-у пратите активност позадинских задатака.

Резиме

  • Background Task — механизам iOS-а за завршавање операција након одласка у позадину, доступан од iOS 4.0.
  • beginBackgroundTask — метод UIApplication-а који региструје задатак и враћа идентификатор за његово завршавање.
  • Expiration handler — обавезан блок кода који систем позива по истеку 30-секундног лимита.
  • endBackgroundTask — обавезан позив за правилно завршавање задатка; без њега апликација остаје у меморији.
  • BGTaskScheduler — модерна алтернатива (iOS 13+) са планирањем, два типа задатака и условима извршавања.
  • backgroundTimeRemaining — својство за проверу преосталог времена и прилагођавање понашања задатка.
  • Користите Background Task за хитне краткорочне операције и BGTaskScheduler за планирана позадинска ажурирања у новим пројектима.

Развићемо мобилну апликацију под кључ

IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.

Разговарајте о пројекту

Прочитајте такође