Introducción: ¿Por qué un desarrollador Swift necesita bases de datos?
Al desarrollar aplicaciones nativas para iOS y macOS, a menudo surge la necesidad de almacenar datos no solo localmente (Core Data, UserDefaults), sino también en un servidor remoto. Esto puede ser análisis del servidor, registro de eventos, sincronización entre dispositivos o un backend completo para la aplicación. Los dos tipos de bases de datos más populares son las relacionales (PostgreSQL) y las orientadas a documentos (MongoDB).
En este artículo, analizaremos cómo conectarse a PostgreSQL y MongoDB desde una aplicación Swift, utilizando bibliotecas y controladores populares. Prestaremos especial atención a la práctica: instalación de dependencias, escritura de consultas y manejo de errores.
1. Trabajo con PostgreSQL desde Swift
PostgreSQL es un potente sistema de gestión de bases de datos relacional, ideal para proyectos donde la integridad de los datos y las consultas SQL complejas son importantes. En Swift podemos trabajar con PostgreSQL de dos formas principales:
- A través del ORM Fluent (parte del framework Vapor) — un enfoque de alto nivel, conveniente para aplicaciones web.
- Directamente a través del controlador (por ejemplo,
PostgresNIO) — control de bajo nivel, adecuado para aplicaciones iOS/macOS.
Consideremos la segunda opción, ya que no requiere Vapor y es adecuada para aplicaciones comunes.
1.1. Conexión a PostgreSQL a través de PostgresNIO
Agregue la dependencia en Package.swift:
dependencies: [ .package(url: "https://github.com/vapor/postgres-nio.git", from: "1.18.0")]Ejemplo de conexión y ejecución de una 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 establece una conexión con un servidor PostgreSQL local, ejecuta un SELECT y muestra los resultados. Importante: nunca almacene contraseñas en el código — use variables de entorno o Keychain.
1.2. Inserción de datos con parámetros
Para protegerse contra la inyección 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. Trabajo con MongoDB desde Swift
MongoDB es una base de datos NoSQL que almacena datos en forma de documentos similares a JSON (BSON). Para Swift existe un excelente controlador MongoSwift.
2.1. Instalación de MongoSwift
Agregue en Package.swift:
dependencies: [ .package(url: "https://github.com/mongodb/mongo-swift-driver.git", from: "1.3.0")]2.2. Conexión y operaciones CRUD
Ejemplo de conexión a MongoDB local e inserción de un 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")
// Inserción de documento let document: Document = ["name": "Bob", "age": 25, "city": "Mosc