URLSession es una API para solicitudes de red en iOS y macOS, parte del framework Foundation que proporciona una interfaz unificada para trabajar con HTTP, HTTPS, descargas en segundo plano y WebSocket. Reemplazó al obsoleto NSURLConnection y se convirtió en la herramienta principal de red para los desarrolladores de Apple. Según Apple Developer Documentation (2025), URLSession maneja más del 90% del tráfico de red en aplicaciones de iPhone y iPad.
Puntos clave
URLSession es una API para operaciones de red presentada por Apple en iOS 7 y macOS 10.9. Reemplazó a NSURLConnection y proporcionó un modelo más flexible y potente para trabajar con la red. La biblioteca admite HTTP/1.1, HTTP/2, HTTP/3 y WebSocket, así como sesiones en segundo plano para la carga de datos.
La principal ventaja de URLSession sobre el antiguo NSURLConnection es el soporte para múltiples conexiones simultáneas a través de una sola sesión, configuraciones personalizables y la capacidad de pausar y reanudar descargas. Una sesión agrupa un conjunto de tareas de red con ajustes compartidos: caché, política de cookies, tiempos de espera, certificados TLS.
En iOS, URLSession funciona con la caché DNS del sistema, la gestión de energía y los procesos en segundo plano. Cuando la aplicación se minimiza, el sistema puede continuar cargando datos a través de una sesión en segundo plano y, al finalizar, notificar a la aplicación mediante un controlador de finalización. Las sesiones en segundo plano son especialmente útiles para descargar archivos grandes, actualizar contenido y sincronizar datos en aplicaciones de documentos y medios. Para trabajar con sesiones en segundo plano, debe implementar URLSessionDelegate y pasar un identificador de configuración al crear la sesión: el sistema utiliza este identificador para restaurar la sesión después de reiniciar la aplicación.
Una ventaja importante de URLSession es el soporte para HTTP/2 y HTTP/3. La multiplexación HTTP/2 permite enviar múltiples solicitudes a través de una sola conexión TCP, lo que reduce la latencia y la carga del servidor. HTTP/3, basado en el protocolo QUIC sobre UDP, proporciona un establecimiento de conexión aún más rápido al eliminar el handshake TCP.
La arquitectura de URLSession consta de tres componentes clave: configuración de sesión, la sesión misma y las tareas. Cada componente es responsable de un aspecto de la interacción de red, y su combinación determina el comportamiento de la aplicación al trabajar con la red.
La configuración establece los parámetros de la sesión, desde tiempos de espera hasta políticas de caché. Existen tres tipos: .default (estándar con caché en disco), .ephemeral (sin guardar caché ni cookies) y .background (para descargas en segundo plano). En la configuración se puede especificar el número máximo de conexiones por host, tiempo de espera de solicitud y recurso, política TLS y proxy.
URLSessionTask es la clase base para todas las operaciones de red. Las subclases principales son: URLSessionDataTask para solicitudes GET y POST que devuelven datos en memoria, URLSessionDownloadTask para descargar archivos al disco, URLSessionUploadTask para enviar archivos al servidor y URLSessionWebSocketTask para trabajar con WebSocket desde iOS 13.
El delegado de sesión recibe eventos sobre el progreso de las tareas: recepción de datos, finalización de descarga, errores de autenticación, redirecciones. URLSessionDelegate y sus subprotocolos permiten interceptar certificados TLS durante la autenticación, gestionar el caché de respuestas a través de URLCache y monitorear el progreso de descarga de archivos grandes. Alternativamente, se pueden usar closures (controladores de finalización) para casos simples donde no se requiere el manejo de eventos intermedios.
El flujo de trabajo básico con URLSession es el siguiente: se crea una configuración, a partir de ella una sesión, luego a través de la sesión se crea una tarea con una solicitud URL y se inicia la tarea. Analicemos un ejemplo de solicitud GET con un closure. Este patrón se utiliza en la mayoría de las aplicaciones iOS para obtener datos de APIs REST, cargar imágenes e interactuar con servicios en la nube.
let url = URL(string: "https://api.example.com/users")!
let session = URLSession.shared
let task = session.dataTask(with: url) { data, response, error in
guard let data = data, error == nil else {
print("Error: \(error!.localizedDescription)")
return
}
if let json = try? JSONSerialization.jsonObject(with: data) {
print("JSON: \(json)")
}
}
task.resume()
El ejemplo utiliza URLSession.shared, un singleton con configuración .default para solicitudes simples. dataTask crea una operación asíncrona pero no la inicia; es necesario llamar a resume(). El closure se ejecuta después de que la solicitud se completa y devuelve data, response o error. Para una sesión personalizada con su propia configuración, use el inicializador URLSession(configuration:), que permite establecer políticas de caché, tiempos de espera, conexiones máximas, encabezados HTTP predeterminados y configuración de proxy para todas las tareas de la sesión. Este enfoque le brinda control total sobre el comportamiento de la red en su aplicación.
URLSession admite la descarga de archivos con capacidad de pausar y reanudar, así como descargas en segundo plano. DownloadTask guarda el archivo en un directorio temporal, y en el closure de finalización debe moverlo a una ubicación permanente.
let url = URL(string: "https://example.com/file.zip")!
let session = URLSession(configuration: .default)
let task = session.downloadTask(with: url) { location, _, _ in
guard let location = location else { return }
let destination = FileManager.default.temporaryDirectory
.appendingPathComponent("file.zip")
try? FileManager.default.moveItem(at: location, to: destination)
}
task.resume()
El parámetro location en el closure apunta a un archivo temporal que debe moverse; de lo contrario, el sistema lo eliminará después de salir del closure. Para rastrear el progreso, use el delegado URLSessionDownloadDelegate con el método didWriteData, que pasa la cantidad de bytes escritos y el tamaño total del archivo; estos datos se pueden usar para mostrar una barra de progreso en la interfaz de usuario. Las sesiones en segundo plano con downloadTask permiten continuar la descarga incluso después de minimizar la aplicación, y al finalizar, el sistema llama al controlador en AppDelegate.
Alamofire es una biblioteca Swift construida sobre URLSession que proporciona una interfaz más declarativa. La elección entre la API nativa y Alamofire depende de la complejidad del proyecto y las preferencias del equipo.
| Criterio | URLSession | Alamofire |
|---|---|---|
| Dependencias | Ninguna, integrado en Foundation | Requiere SPM o CocoaPods |
| Sintaxis | Imperativa con closures | Declarativa con encadenamiento |
| Manejo de JSON | JSONSerialization manual | responseDecodable con Codable |
| Interceptores | Mediante delegados | RequestInterceptor, EventMonitor |
| Progreso | Mediante delegado | downloadProgress, uploadProgress |
Para proyectos simples, URLSession es suficiente y no agrega dependencias. Alamofire se justifica en proyectos con muchas solicitudes de red, manejo complejo de errores y necesidad de sintaxis concisa. Ambas tecnologías comparten la base común de URLSessionConfiguration y son compatibles entre sí. Al elegir, considere que URLSession está completamente controlado por Apple y se actualiza con iOS, mientras que Alamofire requiere que los desarrolladores de la biblioteca mantengan la compatibilidad con las nuevas versiones del sistema operativo.
Swift moderno admite async/await, lo que hace que las solicitudes de red sean más legibles en comparación con los closures. Veamos la misma solicitud GET usando sintaxis asíncrona.
func fetchUsers() async throws -> [User] {
let url = URL(string: "https://api.example.com/users")!
let (data, _) = try await URLSession.shared.data(from: url)
let users = try JSONDecoder().decode([User].self, from: data)
return users
}
El método data(from:) está disponible desde iOS 15 y macOS 12. Devuelve una tupla (Data, URLResponse) y lanza un error en problemas de red. JSONDecoder con un modelo Codable deserializa automáticamente la respuesta, lo que reemplaza el engorroso JSONSerialization del ejemplo anterior.
Para solicitudes POST con cuerpo JSON, se utiliza URLRequest, donde se configuran el método, los encabezados Content-Type y el cuerpo de la solicitud como Data. Async/await hace que este proceso sea conciso y claro, y el manejo de errores es simple mediante un bloque do-catch.
func createUser(name: String) async throws -> User {
var request = URLRequest(url: URL(string: "https://api.example.com/users")!)
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
let body = try JSONEncoder().encode(["name": name])
request.httpBody = body
let (data, _) = try await URLSession.shared.data(for: request)
return try JSONDecoder().decode(User.self, from: data)
}
Preguntas frecuentes
URLSession es el reemplazo moderno de NSURLConnection, presentado en iOS 7. Las principales diferencias incluyen soporte para múltiples conexiones a través de sesiones, suspensión y reanudación de tareas, descargas en segundo plano y WebSocket. NSURLConnection está obsoleto y no se recomienda su uso en proyectos nuevos.
Para rastrear el progreso, use el delegado URLSessionDownloadDelegate con el método urlSession(_:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite). Alternativamente, para dataTask puede suscribirse a URLSessionTaskDelegate y recibir actualizaciones a través de didSendBodyData.
Las descargas en segundo plano se configuran mediante la configuración .background(withIdentifier:). La aplicación registra un controlador de finalización en AppDelegate y recibe resultados incluso después de minimizarse o cerrarse. El sistema gestiona la descarga y notifica a la aplicación a través del delegado sessionDidFinishEvents.
Sí, desde iOS 13, URLSession admite WebSocket a través de la clase URLSessionWebSocketTask. Se crea con el método webSocketTask(with:) y proporciona métodos send, receive con soporte para mensajes de texto y binarios, así como ping/pong para mantener la conexión activa.
Los tiempos de espera se configuran a través de URLSessionConfiguration: la propiedad timeoutIntervalForRequest (espera de respuesta a una solicitud) y timeoutIntervalForResource (tiempo máximo para toda la descarga). Valores predeterminados: 60 segundos para la solicitud y 7 días para el recurso.
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