Background Task é um mecanismo do iOS que permite a um aplicativo concluir uma operação após a transição para o segundo plano. O sistema aloca tempo limitado (até 30 segundos) para executar a tarefa, após o qual o aplicativo é suspenso à força. De acordo com a Apple, 2026, o uso de um expiration handler é um requisito obrigatório para concluir corretamente uma tarefa em segundo plano.
Principais pontos
Background Task é um mecanismo programático do iOS que permite a um aplicativo estender o tempo de execução após a transição para o segundo plano. Quando o usuário minimiza o aplicativo, o sistema chama UIApplicationDelegate.applicationDidEnterBackground. Se uma operação crítica estiver sendo executada naquele momento (salvando dados, enviando uma requisição), o aplicativo pode solicitar tempo adicional através de beginBackgroundTask.
Sem usar Background Task, o aplicativo é suspenso à força em 3–5 segundos após entrar em segundo plano. Todas as operações incompletas são interrompidas: os dados não são salvos, as requisições de rede são abortadas, os estados são perdidos. A Background Task dá ao aplicativo até 30 segundos para concluir essas operações corretamente.
beginBackgroundTask apareceu no iOS 4.0 — a primeira versão com suporte a multitarefa. Antes do iOS 4, o aplicativo era completamente encerrado ao pressionar o botão Home. O iOS 7 introduziu Background Fetch e configuração em segundo plano do URLSession. A partir do iOS 13, a Apple recomenda o BGTaskScheduler para novos projetos, mas o beginBackgroundTask continua relevante para operações de curto prazo.
beginBackgroundTask é um método do UIApplication que registra uma tarefa e retorna um UIBackgroundTaskIdentifier único. O sistema aumenta o temporizador de execução em segundo plano. Quando o tempo expira, o expiration handler é chamado, após o qual o aplicativo deve chamar endBackgroundTask(identifier:) para concluir corretamente a tarefa.
Passo 1 — o aplicativo recebe a notificação didEnterBackground. Passo 2 — beginBackgroundTask(expirationHandler:) é chamado. Passo 3 — a operação crítica (salvamento, requisição de rede) é executada. Passo 4 — ao concluir, endBackgroundTask(identifier:) é chamado. Se a operação não for concluída em 30 segundos — o sistema chama o expiration handler, e o aplicativo deve finalizar a tarefa imediatamente.
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
}
A propriedade backgroundTimeRemaining retorna o número de segundos restantes antes da tarefa em segundo plano ser encerrada à força. O valor diminui em tempo real. Se o aplicativo não estiver em segundo plano — retorna DBL_MAX. Use esta propriedade para adaptar o comportamento: quando restarem menos de 5 segundos, interrompa operações longas e salve o progresso.
Um aplicativo pode registrar várias Background Tasks simultaneamente. Cada tarefa recebe seu próprio identificador. O tempo total de execução é cumulativo — se 3 tarefas forem registradas, o aplicativo pode obter até 90 segundos. No entanto, o sistema pode encerrar o aplicativo antes se os recursos forem esgotados ou o limite da bateria for excedido.
Expiration handler é um bloco de código que o sistema chama quando o tempo alocado para a tarefa em segundo plano expira. Ter um expiration handler é um requisito obrigatório da Apple. Sem ele, o aplicativo pode ser encerrado à força pelo sistema e os dados podem ser perdidos.
O expiration handler deve realizar ações mínimas para salvar o estado do aplicativo: salvar os dados atuais no armazenamento persistente, chamar endBackgroundTask com o identificador correspondente e definir o identificador como .invalid. Dentro do expiration handler é proibido iniciar novas operações longas — o tempo de execução é limitado a 1–2 segundos.
func handleExpiration() {
// Salvando o progresso da execução
saveProgressToUserDefaults()
// Cancelando requisições de rede ativas
currentTask?.cancel()
// Finalizando Background Task
UIApplication.shared.endBackgroundTask(backgroundTaskID)
backgroundTaskID = .invalid
}
// Registro com expiration handler
backgroundTaskID = UIApplication.shared.beginBackgroundTask(
withName: "SaveDocument",
expirationHandler: handleExpiration
)
O erro mais comum é não chamar endBackgroundTask dentro do expiration handler. Neste caso, o sistema continua considerando a tarefa ativa, o aplicativo não transita para o estado Suspenso e a bateria se esgota. O segundo erro é iniciar operações longas dentro do expiration handler. O sistema pode encerrar o aplicativo antes que elas sejam concluídas e os dados serão perdidos.
No expiration handler, o tempo de execução é criticamente limitado — tipicamente menos de 1 segundo. Portanto, dentro do handler não se pode realizar: cálculos complexos, requisições de rede, gravação de grandes volumes de dados no CoreData. Apenas operações atômicas: escrever uma chave no UserDefaults, definir um sinalizador de estado, chamar endBackgroundTask.
Vamos revisar uma implementação completa de Background Task para salvar um documento quando o aplicativo entra em segundo plano. O exemplo inclui registro de tarefa, execução da operação com verificação do tempo restante e conclusão adequada via endBackgroundTask.
Ao entrar em segundo plano, o aplicativo inicia o salvamento de um documento grande. A Background Task fornece até 30 segundos para a operação. Se o tempo expirar — o expiration handler salva os resultados intermediários. Após a conclusão do salvamento, endBackgroundTask é chamado para liberar recursos.
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
}
}
Requisições de rede em segundo plano exigem atenção especial — o expiration handler pode interromper a requisição antes de receber uma resposta. Use URLSession com dataTask e verifique backgroundTimeRemaining antes de enviar. Se restarem menos de 5 segundos — adie o envio até a próxima ativação do aplicativo.
func sendCriticalData(data: Data) {
backgroundTaskID = UIApplication.shared.beginBackgroundTask {
// Salvando dados para reenvio
saveForRetry(data)
self.endBackgroundTask()
}
let task = URLSession.shared.dataTask(with: request) { _, _, error in
if error != nil {
saveForRetry(data)
}
self.endBackgroundTask()
}
task.resume()
}
Para operações longas, monitore UIApplication.shared.backgroundTimeRemaining. Se o valor cair abaixo de um limite (10 segundos), interrompa a operação atual e comece a salvar resultados intermediários. Isso permite uma conclusão adequada antes que o expiration handler seja chamado à força.
Background Task é um mecanismo poderoso, mas seu uso inadequado leva a problemas de bateria e desempenho. Seguir as recomendações da Apple e as práticas comprovadas da comunidade ajudará a evitar erros comuns e garantir uma operação estável do aplicativo.
Conclua a Background Task o mais rápido possível. Cada segundo de execução em segundo plano consome bateria. Tempo ideal — menos de 5 segundos. Se a operação demorar mais — considere usar BGTaskScheduler ou Background Modes. Não prolongue artificialmente a tarefa através de chamadas beginBackgroundTask sem necessidade real.
Armazene UIBackgroundTaskIdentifier como uma propriedade de classe ou estrutura. Nunca o passe como uma variável global — isso leva a conflitos com tarefas múltiplas. Defina o identificador como .invalid após chamar endBackgroundTask para evitar conclusão dupla.
No Simulador do Xcode, mude o aplicativo para o segundo plano através do botão Home (Command + Shift + H). Use Debug — Simulate Background Fetch para testar a ativação em segundo plano. Para simular a expiração do tempo, defina a Variável de Ambiente BACKGROUND_TASK_SIMULATE_EXPIRATION = YES — o expiration handler será chamado em 5 segundos.
// Verificando o tempo restante antes de iniciar a operação
let remaining = UIApplication.shared.backgroundTimeRemaining
guard remaining > 10.0 else {
// Tempo insuficiente — adiar a tarefa
scheduleForNextLaunch()
return
}
// Executando a operação com controle de tempo
backgroundTaskID = UIApplication.shared.beginBackgroundTask {
saveProgress()
self.endBackgroundTask()
}
O expiration handler captura self — isso pode criar um ciclo de retenção se o backgroundTaskID for armazenado como uma propriedade do mesmo objeto. Use [weak self] no closure ou armazene o identificador separadamente. Um ciclo de retenção leva a um vazamento de memória — o objeto não será liberado até que o aplicativo seja encerrado.
Com o lançamento do iOS 13, a Apple apresentou o BGTaskScheduler — um substituto moderno para a antiga API Background Task. Ambos os mecanismos resolvem tarefas semelhantes, mas o BGTaskScheduler oferece mais controle e flexibilidade. Entender as diferenças ajudará a escolher a ferramenta certa para um cenário específico.
| Característica | Background Task | BGTaskScheduler |
|---|---|---|
| Versão iOS | 4.0+ | 13.0+ |
| Tempo máximo | 30 segundos | 30 s / 10 min (processing) |
| Iniciação | didEnterBackground | Agendamento + sistema |
| Garantia de execução | Apenas ao entrar em segundo plano | A qualquer momento conveniente para o sistema |
| Expiration handler | Sim, obrigatório | Sim, via task.expirationHandler |
| Internet | Requerido na inicialização | Disponível via requiresNetworkConnectivity |
| Carregamento | Não requerido | Opcional para processing |
beginBackgroundTask é adequado para operações de curto prazo que precisam ser executadas imediatamente ao entrar em segundo plano: salvar estado, concluir uma requisição de rede, armazenar dados em cache. A API é simples e não requer configuração de Info.plist ou registro de identificadores. Ideal para operações que levam menos de 10 segundos.
BGTaskScheduler é adequado para tarefas que podem ser executadas a qualquer momento conveniente: sincronização periódica, limpeza de cache, atualização de widgets. O próprio sistema seleciona o momento ideal considerando o comportamento do usuário e o estado da bateria. Para operações longas (até 10 minutos), use BGProcessingTask.
Ambas as APIs podem ser usadas no mesmo aplicativo. Background Task — para operações imediatas ao entrar em segundo plano (salvar um rascunho). BGTaskScheduler — para atualizações agendadas (sincronização a cada 6 horas). A separação de responsabilidades garante a preservação adequada dos dados e uma manutenção em segundo plano energeticamente eficiente.
Perguntas frequentes
Sim, beginBackgroundTask pode ser chamado a qualquer momento durante a execução do aplicativo. No entanto, a alocação de tempo do sistema só começará após a transição para o segundo plano. Se o aplicativo estiver em primeiro plano, chamar beginBackgroundTask não tem efeito — backgroundTimeRemaining retorna DBL_MAX, e a tarefa será ativada ao entrar em segundo plano.
Se endBackgroundTask não for chamado, o sistema continua considerando o aplicativo ativo em segundo plano. Após 30 segundos, o expiration handler será chamado, mas se ele também não tiver endBackgroundTask — o aplicativo permanece na memória, esgotando a bateria. No iOS 13+, o sistema encerra à força esse aplicativo após 3 minutos.
O tempo padrão é de 30 segundos. Só pode ser estendido através de Background Modes: Áudio (reprodução), Localização (geolocalização), Bluetooth (BLE). Ou via BGProcessingTask (iOS 13+) — até 10 minutos com carregamento e Wi-Fi. O beginBackgroundTask por si só não fornece uma maneira de aumentar o limite.
Sim, iPadOS suporta totalmente o beginBackgroundTask com as mesmas limitações do iOS. No iPad com Stage Manager, o aplicativo pode permanecer mais tempo na memória — o sistema suspende os aplicativos com menos frequência devido à maior RAM. Mas o limite de 30 segundos para tarefas em segundo plano permanece.
Conecte o dispositivo ao Xcode, inicie o aplicativo, minimize-o — os logs do sistema aparecerão no console. Use sysdiagnose para coletar logs detalhados: acione à força o sysdiagnose a partir do dispositivo (Volume Up + Volume Down + Power). No Navegador de Depuração do Xcode, monitore a atividade das tarefas em segundo plano.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também