BGTaskScheduler es un framework de Apple para planificar y ejecutar tareas en segundo plano en aplicaciones iOS 13 y posteriores. Reemplazó los obsoletos Background Fetch y performFetch, proporcionando una API unificada para trabajar con operaciones en segundo plano. Según Apple Developer Documentation, 2026, el framework incluye dos tipos de tareas: BGProcessingTask para operaciones largas y BGAppRefreshTask para actualizaciones cortas de contenido.
Puntos clave
BGTaskScheduler es un framework de sistema de Apple introducido en iOS 13 que gestiona de forma centralizada la ejecución de tareas en segundo plano. Antes de su aparición, los desarrolladores usaban UIApplication backgroundTasks, performFetch y el manejo de eventos en appDelegate, lo que provocaba fragmentación del código y comportamiento impredecible.
El framework funciona según el principio de planificación diferida: la aplicación registra tareas con identificadores únicos, y iOS mismo determina el momento óptimo para ejecutarlas. El sistema tiene en cuenta el nivel de batería, la actividad del usuario, el estado de la red y otros factores.
Las capacidades principales incluyen trabajar tanto con operaciones cortas como largas en segundo plano. A diferencia de AlarmManager en Android, BGTaskScheduler no garantiza una hora exacta de ejecución — el sistema se reserva el derecho de retrasar una tarea si las condiciones no son favorables.
BGTaskScheduler utiliza una arquitectura basada en manejadores (handlers). La aplicación registra un manejador para cada tipo de tarea, y el sistema lo llama cuando llega el momento adecuado. El framework en sí no ejecuta la tarea directamente — solo notifica a la aplicación que ha llegado el momento de ejecutarla.
El registro comienza declarando el identificador de la tarea en Info.plist a través del array BGTaskSchedulerPermittedIdentifiers. Luego, en el código de la aplicación, se llama al método registerHandler(forTaskWithIdentifier:) con un closure como manejador.
import BackgroundTasks
let taskID = "com.example.app.refresh"
BGTaskScheduler.shared.registerHandler(
forTaskWithIdentifier: taskID,
using: DispatchQueue.global()
) { task in
task.expirationHandler = {
// llamado al finalizar forzosamente
}
processBackgroundTask(task as! BGAppRefreshTask)
}
Después del registro, la aplicación debe solicitar explícitamente la ejecución de la tarea mediante submitTaskRequest. La solicitud contiene el identificador de la tarea y la fecha más temprana posible de inicio. El sistema guarda la solicitud y la procesa cuando considera que las condiciones son adecuadas.
let request = BGAppRefreshTaskRequest(
identifier: taskID
)
request.earliestBeginDate = Date(timeIntervalSinceNow: 3600)
do {
try BGTaskScheduler.shared.submit(request)
} catch {
print("Error de planificación: \(error)")
}
BGTaskScheduler proporciona dos tipos principales de tareas, cada uno diseñado para su propio caso de uso. Elegir el tipo correcto afecta directamente la probabilidad de que el sistema ejecute la tarea con éxito.
BGAppRefreshTask está diseñada para actualizaciones cortas de contenido en segundo plano: cargar nuevos datos, sincronizar con el servidor, actualizar widgets. El tiempo de ejecución está limitado a 30 segundos, después de los cuales el sistema finaliza la tarea forzosamente. Este tipo de tarea se ejecuta con más frecuencia que BGProcessingTask y tiene mayor prioridad.
BGProcessingTask está diseñada para operaciones más largas: procesar archivos multimedia, indexar Core Data, crear copias de seguridad. La tarea puede ejecutarse hasta varios minutos, pero el sistema la inicia con menos frecuencia y solo en condiciones favorables — conectado a la corriente, Wi-Fi estable y baja carga del dispositivo.
| Parámetro | BGAppRefreshTask | BGProcessingTask |
|---|---|---|
| Límite de tiempo | 30 segundos | varios minutos |
| Frecuencia de inicio | alta | baja |
| Condiciones | cualquiera | corriente + Wi-Fi |
| Requiere corriente | no | recomendado |
| Ejemplo | actualizar feed | procesar video |
El registro correcto es un requisito obligatorio para que BGTaskScheduler funcione. Si una tarea no está registrada en Info.plist, el sistema ignorará cualquier solicitud para ejecutarla.
El archivo Info.plist debe incluir el array BGTaskSchedulerPermittedIdentifiers con una lista de identificadores de cadena. Cada identificador debe ser único dentro de la aplicación. Apple recomienda usar la notación inversa de dominio.
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>com.example.app.refresh</string>
<string>com.example.app.processing</string>
</array>
Para planificar una tarea, use el método submitTaskRequest. Si ya no se necesita una tarea, se puede cancelar mediante cancelTaskRequest o cancelAllTaskRequests. El sistema también cancela automáticamente las tareas cuando se elimina la aplicación o se restablecen los datos.
BGTaskScheduler proporciona la capacidad de rastrear el estado de las tareas planificadas a través de getPendingTaskRequests. Este método devuelve una lista de todas las solicitudes activas con información sobre su tipo, identificador y earliestBeginDate. Para cada solicitud, se puede verificar si ya se completó o canceló, y decidir si reprogramarla.
Es importante tener en cuenta que el sistema no proporciona una devolución de llamada directa sobre el éxito de una tarea en segundo plano — el manejador mismo debe informar el resultado a través de las propiedades de la tarea. setTaskCompleted permite marcar una tarea como completada con éxito, después de lo cual el sistema puede iniciar la siguiente tarea planificada de este tipo. Si una tarea no llama a setTaskCompleted, el sistema la considera completada por tiempo de espera o finalización forzada.
Para diagnóstico, se recomienda usar OSLog en el manejador y ver los registros a través de Console.app en Mac. Apple también proporciona la herramienta MetricKit para analizar el rendimiento de las tareas en segundo plano — recopila datos sobre el tiempo de ejecución, el consumo de energía y la frecuencia de inicio que se pueden usar para la optimización.
// Cancelar tarea específica
BGTaskScheduler.shared.cancel(taskRequestWithIdentifier: taskID)
// Cancelar todas las tareas
BGTaskScheduler.shared.cancelAllTaskRequests()
// Verificar tareas planificadas
BGTaskScheduler.shared.getPendingTaskRequests { requests in
print("Planificadas \(requests.count) tareas")
}
BGTaskScheduler impone limitaciones estrictas al trabajo en segundo plano. El sistema puede retrasar una tarea indefinidamente si las condiciones no son favorables. Los desarrolladores deben entender que el framework no está diseñado para tareas en tiempo real.
Las limitaciones clave incluyen: el sistema no garantiza la ejecución de la tarea en el momento especificado, el número máximo de tareas simultáneas está limitado, y el consumo de energía está estrictamente controlado. Ejecutar varias tareas en sucesión puede resultar en su fusión o cancelación.
Para aumentar la probabilidad de ejecución, se recomienda establecer earliestBeginDate no antes de 1 hora para BGProcessingTask y 15 minutos para BGAppRefreshTask. También es importante manejar expirationHandler — si una tarea no cumple con su límite de tiempo, el sistema llama a este manejador para una finalización adecuada. La reprogramación debe realizarse dentro del propio manejador para mantener un ciclo continuo de trabajo en segundo plano.
Otra limitación importante se refiere a las solicitudes de red. BGTaskScheduler no garantiza una conexión de red activa durante la ejecución de la tarea. La aplicación debe verificar independientemente la disponibilidad de la red a través de NWPathMonitor y aplazar el procesamiento si la conexión no está disponible. Esto difiere de Android JobScheduler, que puede activar una tarea solo cuando está conectado a un tipo específico de red. En la práctica, los desarrolladores a menudo combinan BGTaskScheduler con sesiones URL de fondo de NSURLSession para una carga de datos confiable.
A partir de macOS Catalina, BGTaskScheduler también está disponible en Mac. Esto permite crear tareas en segundo plano multiplataforma para aplicaciones UIKit que se ejecutan en Apple Silicon. En watchOS, el framework tiene funcionalidad limitada — solo están disponibles BGAppRefreshTask cortas para actualizar complicaciones y sincronizar datos con el iPhone. Los desarrolladores deben tener en cuenta las diferencias de plataforma al planificar la arquitectura en segundo plano.
Apple proporciona varias herramientas para depurar BGTaskScheduler. El comando e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.example.task"] en lldb inicia forzosamente una tarea en segundo plano, omitiendo las limitaciones del sistema. Xcode tiene un indicador Simulate Background Fetch en el menú Debug que emula una actualización corta en segundo plano. MetricKit se usa para el análisis de rendimiento — recopila información sobre la frecuencia de inicio, la duración de la ejecución y el consumo de energía de cada tarea. Estos datos ayudan a optimizar la frecuencia de planificación y elegir el tipo de tarea correcto.
En la práctica, BGTaskScheduler es adecuado para actualizar datos de widgets, sincronización de iCloud, procesar notificaciones push con contenido e indexar para la búsqueda de Spotlight. No es adecuado para análisis en tiempo real, aplicaciones de chat o cualquier tarea que requiera ejecución inmediata.
Para un estudio en profundidad de BGTaskScheduler, Apple recomienda la documentación oficial de WWDC: la sesión "Advances in Background Tasks" (2020) cubre la migración desde APIs obsoletas, y "Background Tasks in Practice" (2021) contiene casos de uso reales. La sección Energy Efficiency Guide también es útil, describiendo cómo el framework se integra en la estrategia general de ahorro de energía de Apple. Los ejemplos de código están disponibles en el repositorio oficial de Apple Developer en GitHub con proyectos completos para iOS y macOS.
Preguntas frecuentes
Background Fetch estaba limitado a una tarea en segundo plano por aplicación y no tenía mecanismo de prioridades. BGTaskScheduler admite múltiples tareas con diferentes tipos, proporciona una API unificada y gestión automática de energía.
Apple no establece un límite explícito en la cantidad de identificadores registrados, pero en la práctica se recomienda usar no más de 5–10 tareas. Un número mayor reduce la probabilidad de que cada tarea específica se ejecute debido a la competencia por los recursos del sistema.
Para depurar, use el comando e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.example.task"] en lldb. Inicia forzosamente una tarea, omitiendo las limitaciones del sistema. También está disponible el indicador Xcode Simulate Background Fetch en el menú Debug.
Sí, BGTaskScheduler puede iniciar un proceso incluso si la aplicación fue cerrada forzosamente por el usuario. Sin embargo, el sistema puede aplicar demoras adicionales, y no todos los tipos de tareas garantizan la ejecución en este escenario.
El sistema llama a expirationHandler, indicando a la tarea que debe finalizar. Si la aplicación ignora esta señal y continúa funcionando, iOS finaliza el proceso forzosamente. Después de eso, el sistema puede reducir la prioridad de todas las tareas en segundo plano de la aplicación.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también