API em Swift: da teoria às requisições reais
\n\nTodo desenvolvedor iOS, mais cedo ou mais tarde, enfrenta a necessidade de comunicação do aplicativo com o servidor. Seja para carregar um feed de notícias, enviar dados de formulário ou fazer streaming em tempo real — não há como evitar uma API (Application Programming Interface). Mas qual protocolo escolher? O clássico REST, o flexível GraphQL ou o ultrarrápido gRPC?
\n\nNeste artigo, não vamos apenas listar prós e contras. Vamos analisar o trabalho com API em Swift com exemplos reais, mostrar código e dar dicas práticas. Você aprenderá como estruturar corretamente a camada de rede, quais bibliotecas usar e quando cada abordagem se torna a melhor escolha.
\n\nSe você programa em Swift e quer que seu aplicativo se comunique com o backend de forma rápida, confiável e elegante — este artigo é para você. Vamos lá!
\n\nREST API em Swift: o clássico que nunca envelhece
\n\nREST (Representational State Transfer) é um estilo arquitetural que utiliza métodos HTTP (GET, POST, PUT, DELETE) para trabalhar com recursos. A maioria das APIs públicas (GitHub, Twitter, Stripe) são construídas sobre REST. Para o desenvolvedor Swift, isso significa trabalhar com JSON, URLSession ou Alamofire.
\n\nRequisição GET básica com URLSession
\n\nVamos começar com o mais simples — obter dados. Imagine que precisamos carregar uma lista de usuários do JSONPlaceholder:
\n\nimport Foundation\n\nstruct User: Codable {\n let id: Int\n let name: String\n let email: String\n}\n\nfunc fetchUsers() async throws -> [User] {\n let url = URL(string: "https://jsonplaceholder.typicode.com/users")!\n let (data, response) = try await URLSession.shared.data(from: url)\n \n guard let httpResponse = response as? HTTPURLResponse,\n (200...299).contains(httpResponse.statusCode) else {\n throw URLError(.badServerResponse)\n }\n \n return try JSONDecoder().decode([User].self, from: data)\n}\n\nTask {\n do {\n let users = try await fetchUsers()\n print("Carregados \\(users.count) usuários")\n } catch {\n print("Erro: \\(error.localizedDescription)")\n }\n}\n\nObserve o uso de async/await — esta é a forma moderna de trabalhar com código assíncrono em Swift. O código ficou legível e conciso, sem closures e callbacks.
Requisição POST com Alamofire
\n\nAlamofire é a biblioteca mais popular para trabalho de rede em Swift. Ela simplifica o tratamento de erros, a codificação de parâmetros e o upload de arquivos. Aqui está um exemplo de envio de dados:
\n\nimport Alamofire\n\nstruct NewUser: Encodable {\n let name: String\n let email: String\n}\n\nAF.request("https://jsonplaceholder.typicode.com/users",\n method: .post,\n parameters: NewUser(name: "João", email: "joao@example.com"),\n encoder: JSONParameterEncoder.default)\n .validate()\n .responseDecodable(of: User.self) { response in\n switch response.result {\n case .success(let user):\n print("Usuário criado com id: \\(user.id)")\n case .failure(let error):\n print("Erro: \\(error.localizedDescription)")\n }\n }\n\nDica: Use .validate() — isso verificará automaticamente o código de status e converterá erros HTTP em erros do Alamofire. Seu código ficará mais limpo e a depuração, mais fácil.
Quando o REST é a melhor escolha?
\n- \n
- Você tem um aplicativo CRUD simples (anotações, lista de tarefas). \n
- A API fornece endpoints fixos. \n
- Você não precisa de aninhamento complexo de dados. \n
GraphQL em Swift: flexibilidade nas consultas
\n\nGraphQL é uma linguagem de consulta que permite ao cliente solicitar exatamente os dados de que precisa. Sem over-fetching (campos extras) ou under-fetching (várias requisições necessárias). Para Swift, existe a excelente biblioteca Apollo iOS