Cliente HTTP en Swift: haciendo solicitudes correctamente de la A a la Z

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción



Las aplicaciones modernas de iOS y macOS rara vez prescinden de la interacción con servidores remotos. Ya sea cargar datos de un feed de noticias, enviar un formulario de registro o sincronizar archivos, todas estas operaciones requieren una implementación adecuada de un cliente HTTP. En el ecosistema Swift, el desarrollador tiene a su disposición el potente framework integrado URLSession, que cada año se vuelve más conveniente gracias a la incorporación de async/await.



En este artículo, analizaremos cómo crear correctamente solicitudes HTTP en Swift, comenzando con las estructuras básicas y terminando con técnicas avanzadas de manejo de errores y serialización de datos. Aprenderá a escribir código de red limpio, seguro y eficiente para sus aplicaciones.



Fundamentos de URLSession: primera solicitud HTTP



La clase URLSession es la base de cualquier trabajo de red en Swift. Gestiona la configuración, el almacenamiento en caché, las sesiones y la ejecución directa de las solicitudes. Veamos una solicitud GET simple para obtener datos de un servidor.



Creación de una solicitud GET simple



import Foundation

// 1. Creamos la URLguard let url = URL(string: "https://api.example.com/users") else { print("URL inválida") return}

// 2. Creamos la solicitud (por defecto GET)var request = URLRequest(url: url)request.httpMethod = "GET"request.setValue("application/json", forHTTPHeaderField: "Accept")

// 3. Creamos la sesiónlet session = URLSession.shared

// 4. Ejecutamos la solicitud (método antiguo con closure)let task = session.dataTask(with: request) { data, response, error in if let error = error { print("Error en la solicitud: \\(error.localizedDescription)") return } guard let httpResponse = response as? HTTPURLResponse, (200...299).contains(httpResponse.statusCode) else { print("El servidor devolvió un error") return } if let data = data, let jsonString = String(data: data, encoding: .utf8) { print("Datos recibidos: \\(jsonString)") }}task.resume() // ¡Importante! Iniciamos la tarea


Puntos clave: siempre verifique el estado de la respuesta (200...299), no olvide llamar a resume() y maneje los posibles errores. En proyectos reales, este código generalmente se extrae en una capa de servicio separada.



Enfoque moderno: async/await



A partir de Swift 5.5, es posible usar async/await, lo que hace que el código sea mucho más legible y elimina la "pirámide de closures".



func fetchUsers() async throws -> Data {    guard let url = URL(string: "https://api.example.com/users") else {        throw URLError(.badURL)    }        var request = URLRequest(url: url)    request.httpMethod = "GET"    request.setValue("application/json", forHTTPHeaderField: "Accept")        let (data, response) = try await URLSession.shared.data(for: request)        guard let httpResponse = response as? HTTPURLResponse,          (200...299).contains(httpResponse.statusCode) else {        throw URLError(.badServerResponse)    }        return data}


Este código se puede llamar desde cualquier función o tarea asíncrona, lo que simplifica significativamente la lógica.



Trabajo con JSON: Codable y modelos de datos



Rara vez los datos llegan en formato "crudo". La mayoría de las veces trabajamos con JSON. Swift ofrece una solución elegante: el protocolo Codable (que combina Encodable y Decodable).



Creación del modelo y decodificación



// 1. Definimos la estructura de datosstruct User: Codable {    let id: Int    let name: String    let email: String}

// 2. Función asíncrona para obtener un array de usuariosfunc fetchUsers() async throws -> [User] { let data = try await fetchUsersData() // del ejemplo anterior let decoder = JSONDecoder() return try decoder.decode

Blogs

Book Recommendations