Introdução: Por que um desenvolvedor Swift precisa de bancos de dados?
Ao desenvolver aplicativos nativos para iOS e macOS, muitas vezes surge a necessidade de armazenar dados não apenas localmente (Core Data, UserDefaults), mas também em um servidor remoto. Isso pode ser para análise no servidor, registro de logs, sincronização entre dispositivos ou um backend completo para o aplicativo. Os dois tipos mais populares de bancos de dados são os relacionais (PostgreSQL) e os orientados a documentos (MongoDB).
Neste artigo, vamos explorar como conectar-se ao PostgreSQL e MongoDB a partir de um aplicativo Swift, usando bibliotecas e drivers populares. Daremos atenção especial à prática: instalação de dependências, escrita de consultas e tratamento de erros.
1. Trabalhando com PostgreSQL a partir do Swift
PostgreSQL é um poderoso SGBD relacional, ideal para projetos onde a integridade dos dados e consultas SQL complexas são importantes. No Swift, podemos trabalhar com PostgreSQL de duas maneiras principais:
- Através do ORM Fluent (parte do framework Vapor) — uma abordagem de alto nível, conveniente para aplicações web.
- Diretamente através do driver (por exemplo,
PostgresNIO) — controle de baixo nível, adequado para aplicativos iOS/macOS.
Vamos considerar a segunda opção, pois ela não requer o Vapor e é adequada para aplicativos comuns.
1.1. Conectando ao PostgreSQL via PostgresNIO
Adicione a dependência no Package.swift:
dependencies: [ .package(url: "https://github.com/vapor/postgres-nio.git", from: "1.18.0")]Exemplo de conexão e execução de consulta:
import PostgresNIOimport NIOCoreimport NIOPosix
func queryPostgres() async throws { let eventLoopGroup = MultiThreadedEventLoopGroup(numberOfThreads: 1) defer { try? eventLoopGroup.syncShutdownGracefully() }
let config = PostgresConnection.Configuration( host: "localhost", port: 5432, username: "swift_user", password: "secret", database: "test_db", tls: .disable )
let connection = try await PostgresConnection.connect( on: eventLoopGroup.next(), configuration: config ) defer { try? connection.close() }
let rows = try await connection.query("SELECT id, name FROM users LIMIT 5;", logger: nil) for try await row in rows { let id = try row.decode(Int.self, column: "id") let name = try row.decode(String.self, column: "name") print("ID: \\(id), Name: \\(name)") }}Este código estabelece uma conexão com o servidor PostgreSQL local, executa um SELECT e exibe os resultados. Importante: nunca armazene senhas no código — use variáveis de ambiente ou o Keychain.
1.2. Inserindo dados com parâmetros
Para proteção contra injeção de SQL, use consultas parametrizadas:
let name = "Alice"let age = 30try await connection.query( "INSERT INTO users (name, age) VALUES ($1, $2);", params: [.string(name), .int(age)], logger: nil)2. Trabalhando com MongoDB a partir do Swift
MongoDB é um banco de dados NoSQL que armazena dados na forma de documentos semelhantes a JSON (BSON). Para Swift, existe um excelente driver chamado MongoSwift.
2.1. Instalação do MongoSwift
Adicione no Package.swift:
dependencies: [ .package(url: "https://github.com/mongodb/mongo-swift-driver.git", from: "1.3.0")]2.2. Conexão e operações CRUD
Exemplo de conexão ao MongoDB local e inserção de um documento:
import MongoSwift
func mongoExample() async throws { let client = try MongoClient("mongodb://localhost:27017") defer { try? client.syncClose() }
let db = client.db("test_database") let collection = db.collection("users")
// Inserção de documento let document: Document = ["name": "Bob", "age": 25, "city": "Mosc