Programación asíncrona en Swift: guía completa en la práctica

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

Programación asíncrona en Swift: guía completa en la práctica



La programación asíncrona es uno de los conceptos clave del desarrollo moderno para iOS y macOS. En Swift, a partir de la versión 5.5, apareció un potente sistema de Structured Concurrency, que hizo que trabajar con asincronía fuera simple y seguro. En este artículo analizaremos las herramientas principales: async/await, Task, Actor y Sendable, y mostraremos su aplicación en ejemplos reales.



1. Fundamentos de async/await: cómo dejar de escribir closures y empezar a vivir



Antes de la llegada de async/await, el código asíncrono en Swift se escribía con closures y delegados, lo que a menudo llevaba al «infierno de los callbacks». El enfoque moderno permite escribir código asíncrono de forma tan lineal como el síncrono.



Se puede declarar una función asíncrona con la palabra clave async. La llamada a dicha función requiere un contexto que soporte asincronía y la palabra clave await.



// Ejemplo de función asíncrona para cargar datosfunc fetchUserData(userID: String) async throws -> User {    let url = URL(string: "https://api.example.com/users/\\(userID)")!    let (data, response) = try await URLSession.shared.data(from: url)        guard let httpResponse = response as? HTTPURLResponse,          httpResponse.statusCode == 200 else {        throw URLError(.badServerResponse)    }        let user = try JSONDecoder().decode(User.self, from: data)    return user}

// UsoTask { do { let user = try await fetchUserData(userID: "123") print("User name: \\(user.name)") } catch { print("Error: \\(error)") }}


Características clave:

  • async — marcador de función asíncrona
  • await — punto de suspensión de la ejecución
  • La función puede ser tanto async como throws al mismo tiempo
  • El hilo no se bloquea — durante la espera puede realizar otro trabajo


2. Task y TaskGroup: gestión de tareas paralelas



Task es la unidad básica de trabajo asíncrono. Crea una nueva tarea asíncrona que se ejecuta en el grupo global de hilos. TaskGroup permite lanzar varias tareas en paralelo y recopilar sus resultados.



Creación y cancelación de Task



// Creación de una tarealet task = Task {    let result = await performLongOperation()    return result}

// Obtención del resultadolet value = await task.value

// Cancelación de la tareatask.cancel()

// Verificación de cancelación dentro de la tareafunc performLongOperation() async -> String { // Verificamos si la tarea no ha sido cancelada guard !Task.isCancelled else { return "Cancelled" } // Emulamos un trabajo largo try? await Task.sleep(nanoseconds: 2_000_000_000) return "Completed"}


Procesamiento paralelo con TaskGroup



// Carga de varias imágenes en paralelofunc loadImages(urls: [URL]) async throws -> [UIImage] {    return try await withThrowingTaskGroup(of: UIImage.self) { group in        var images: [UIImage] = []        images.reserveCapacity(urls.count)                for url in urls {            group.addTask {                let (data, _) = try await URLSession.shared.data(from: url)                guard let image = UIImage(data: data) else {                    throw URLError(.cannotDecodeContentData)                }                return image            }        }                // Recopilamos los resultados a medida que estén listos        for try await image in group {            images.append(image)        }                return images    }}


Importante: TaskGroup gestiona automáticamente el ciclo de vida de las tareas hijas

Blogs

Book Recommendations