Введение: зачем разработчику Swift базы данных?
Современные приложения для iOS и macOS редко обходятся без хранения данных. Будь то список задач, профиль пользователя или каталог товаров — данные нужно где-то сохранять и извлекать. Swift, как основной язык экосистемы Apple, предоставляет мощные инструменты для работы с базами данных (БД). В этой статье мы разберём, как начинающему разработчику подключиться и выполнять CRUD-операции (создание, чтение, обновление, удаление) с двумя популярными системами: реляционной PostgreSQL и документо-ориентированной MongoDB.
Мы будем использовать серверный фреймворк Vapor (на базе SwiftNIO) для работы с PostgreSQL, и популярный драйвер MongoKitten для MongoDB. Оба варианта отлично подходят для бэкенда на Swift. Если вы только начинаете — не бойтесь: весь код будет простым и с пояснениями.
1. PostgreSQL и Swift: классика реляционных БД
PostgreSQL — мощная реляционная база данных с поддержкой SQL. Для Swift лучший способ взаимодействия — фреймворк Vapor и его ORM Fluent. Fluent позволяет работать с таблицами как с обычными Swift-структурами.
1.1. Настройка проекта Vapor
Сначала установите Vapor Toolbox и создайте проект:
brew install vapor
vapor new MyApp
cd MyApp
Добавьте зависимость для PostgreSQL в Package.swift:
dependencies: [
.package(url: "https://github.com/vapor/vapor.git", from: "4.0.0"),
.package(url: "https://github.com/vapor/fluent.git", from: "4.0.0"),
.package(url: "https://github.com/vapor/fluent-postgres-driver.git", from: "2.0.0")
]
1.2. Модель и миграция
Создадим простую модель User:
import Fluent
import Vapor
final class User: Model, Content {
static let schema = "users"
@ID(key: .id)
var id: UUID?
@Field(key: "name")
var name: String
@Field(key: "email")
var email: String
init() { }
init(id: UUID? = nil, name: String, email: String) {
self.id = id
self.name = name
self.email = email
}
}
Теперь миграция для создания таблицы:
struct CreateUser: Migration {
func prepare(on database: Database) -> EventLoopFuture<Void> {
database.schema("users")
.id()
.field("name", .string, .required)
.field("email", .string, .required)
.create()
}
func revert(on database: Database) -> EventLoopFuture<Void> {
database.schema("users").delete()
}
}
Зарегистрируйте миграцию в configure.swift:
app.migrations.add(CreateUser())
1.3. CRUD-операции
Создание записи (Create):
let user = User(name: "Иван", email: "ivan@example.com")
try await user.save(on: database)
Чтение (Read):
let users = try await User.query(on: database).all()
let user = try await User.find(id, on: database)
Обновление (Update):
guard let user = try await User.find(id, on: database) else { return }
user.name = "Новое имя"
try await user.update(on: database)
Удаление (Delete):
guard let user = try await User.find(id, on: database) else { return }
try await user.delete(on: database)
Fluent автоматически генерирует SQL-запросы, что сильно упрощает жизнь новичкам.
2. MongoDB и Swift: гибкость NoSQL
MongoDB — документная БД, где данные хранятся в формате BSON (бинарный JSON). Для Swift мы используем библиотеку MongoKitten — зрелый и активно поддерживаемый драйвер.
2.1. Подключение MongoKitten
Добавьте зависимость в Package.swift:
dependencies: [
.package(url: "https://github.com/orlandos-nl/MongoKitten.git", from: "7.0.0")
]
Подключение к локальной MongoDB (по умолчанию порт 27017):
import MongoKitten
let db = try await MongoDatabase.connect(to: "mongodb://localhost:27017/mydb")
2.2. Работа с коллекциями
В MongoDB аналог таблицы — коллекция. Создадим коллекцию users и вставим документ:
let usersCollection = db["users"]
let newUser: Document = [
"name": "Мария",
"email": "maria@example.com",
"age": 28
]
try await usersCollection.insert(newUser)
Чтение данных (Find):
let allUsers = try await usersCollection.find().drain()
let filtered = try await usersCollection.find("name" == "Мария").drain()
Обновление документа:
try await usersCollection.updateOne(
where: "name" == "Мария",
setting: ["age": 29]
)
Удаление:
try await usersCollection.deleteOne(where: "name" == "Мария")
MongoKitten поддерживает агрегации, индексы и транзакции (начиная с версии 4.0 MongoDB). Для начинающих этих операций вполне достаточно.
3. Сравнение PostgreSQL и MongoDB для Swift-проекта
Какую БД выбрать? Вот ключевые различия:
- Структура данных: PostgreSQL требует жёсткой схемы (таблицы, типы полей). MongoDB — гибкая, поля могут различаться в разных документах.
- Производительность: PostgreSQL быстрее на сложных JOIN-запросах. MongoDB — на операциях с большими объёмами однотипных документов.
- Инструменты для Swift: Vapor + Fluent — зрелое решение для PostgreSQL. MongoKitten — мощный, но имеет меньше примеров в русскоязычном сообществе.
- Когда что выбирать: Если