Introdução à Programação Assíncrona em Swift
Aplicativos modernos para iOS e macOS exigem alta capacidade de resposta e desempenho. A programação assíncrona em Swift permite executar operações longas (requisições de rede, manipulação de arquivos, processamento de dados) sem bloquear a thread principal (Main Thread). A partir da versão Swift 5.5, a Apple apresentou o poderoso modelo Swift Concurrency, baseado nas palavras-chave async e await, que simplifica significativamente a escrita de código assíncrono em comparação com closures tradicionais (completion handlers) ou DispatchQueue.
Neste guia, abordaremos detalhadamente todos os conceitos-chave: desde os fundamentos de async/await até tópicos avançados, como Actors e Task Groups. Você aprenderá a escrever código assíncrono seguro, legível e eficiente para seus projetos em Swift.
Fundamentos de async/await em Swift
As palavras-chave async e await são o coração do Swift Concurrency. Elas permitem escrever código assíncrono que se parece com código síncrono, melhorando significativamente a legibilidade e reduzindo o número de erros.
Declarando uma função assíncrona
Para declarar uma função como assíncrona, adicione a palavra-chave async após a lista de parâmetros, mas antes do tipo de retorno. Essa função pode pausar sua execução.
func fetchUserData(from url: URL) async throws -> Data { let (data, response) = try await URLSession.shared.data(from: url) // Verificação do status HTTP guard let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else { throw URLError(.badServerResponse) } return data}Chamando uma função assíncrona com await
Para chamar uma função assíncrona, use a palavra-chave await. Ela indica que o código atual pode pausar neste ponto até obter o resultado.
func loadProfile() async { let url = URL(string: "https://api.example.com/user/profile")! do { let data = try await fetchUserData(from: url) // Processamento dos dados (ex.: decodificação JSON) print("Dados recebidos: \\(data.count) bytes") } catch { print("Erro ao carregar perfil: \\(error.localizedDescription)") }}Async let para tarefas paralelas
Se você precisar executar várias operações assíncronas independentes simultaneamente, use a construção async let. Isso permite iniciar tarefas em paralelo e aguardar todos os resultados.
func loadDashboardData() async -> Dashboard { async let user = fetchUserData(from: URL(string: "https://api.example.com/user")!) async let posts = fetchUserData(from: URL(string: "https://api.example.com/posts")!) async let notifications = fetchUserData(from: URL(string: "https://api.example.com/notifications")!)
// Aguarda todos os resultados let (userData, postsData, notifData) = await (try user, try posts, try notifications) return Dashboard(user: userData, posts: postsData, notifications: notifData)}Task e Structured Concurrency
O Swift Concurrency é baseado no conceito de Structured Concurrency. Isso significa que cada tarefa assíncrona tem um tempo de vida claro e uma relação pai-filho. O bloco de construção principal é o Task.
Criando uma nova tarefa
Task cria uma nova unidade de trabalho assíncrona. Você pode criar uma tarefa em um contexto síncrono (por exemplo, em viewDidLoad).
class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Cria uma nova tarefa para executar trabalho assíncrono Task { let data = try await fetchUserData(from: URL(string: "https://