Datenbankmigrationen in Swift (iOS/macOS)
Die Entwicklung von Anwendungen für iOS und macOS erfordert oft die Arbeit mit lokalen Datenbanken. Mit der Weiterentwicklung der Anwendung ändert sich die Datenstruktur unweigerlich: neue Felder werden hinzugefügt, Typen geändert oder veraltete Entitäten entfernt. Ohne einen korrekten Migrationsmechanismus können diese Änderungen zum Verlust von Benutzerdaten oder zum Absturz der Anwendung führen. In diesem Artikel betrachten wir die wichtigsten Tools und Ansätze zur Durchführung von Datenbankmigrationen in Swift und geben praktische Beispiele für gängige Lösungen.
Warum sind Migrationen wichtig?
Datenbankmigrationen gewährleisten:
- Datenerhalt — Benutzereinträge gehen bei Schemaaktualisierungen nicht verloren.
- Abwärtskompatibilität — die Anwendung funktioniert weiterhin mit alten Datenversionen.
- Entwicklungsflexibilität — die Möglichkeit, das Datenmodell iterativ ohne manuelle Eingriffe zu ändern.
Wichtige Tools für Migrationen in Swift
1. Core Data + NSPersistentContainer
Das integrierte Apple-Framework bietet automatische und leichte Migrationen. Für komplexe Änderungen wird manuelle Modellversionierung verwendet.
// Konfiguration des Containers mit Migrationsunterstützunglet container = NSPersistentContainer(name: "MyAppModel")container.persistentStoreDescriptions.first?.shouldMigrateStoreAutomatically = truecontainer.persistentStoreDescriptions.first?.shouldInferMappingModelAutomatically = true
container.loadPersistentStores { description, error in if let error = error { fatalError("Failed to load store: \\(error)") }}Für manuelle Migrationen werden Modellversionen (.xcdatamodeld) und NSMappingModel erstellt:
let sourceModel = NSManagedObjectModel(contentsOf: sourceURL)!let destinationModel = NSManagedObjectModel(contentsOf: destinationURL)!let mappingModel = NSMappingModel(from: [sourceModel, destinationModel], forSourceModel: sourceModel, destinationModel: destinationModel)
let manager = NSMigrationManager(sourceModel: sourceModel, destinationModel: destinationModel)try? manager.migrateStore(from: sourceURL, sourceType: NSSQLiteStoreType, options: nil, with: mappingModel, toDestinationURL: destinationURL, destinationType: NSSQLiteStoreType, destinationOptions: nil)2. GRDB.swift — moderner SQLite-Treiber
GRDB.swift bietet einen flexiblen Migrationsmechanismus basierend auf der Registrierung von Schritten. Migrationen werden sequenziell und atomar ausgeführt.
import GRDB
var migrator = DatabaseMigrator()
// Registrierung der ersten Migrationmigrator.registerMigration("v1_create_users") { db in try db.create(table: "users") { t in t.autoIncrementedPrimaryKey("id") t.column("name", .text).notNull() t.column("email", .text).unique() }}
// Registrierung der zweiten Migration (Feld hinzufügen)migrator.registerMigration("v2_add_age") { db in try db.alter(table: "users") { t in t.add(column: "age", .integer).defaults(to: 0) }}
// Anwendung der Migrationen beim Start der Anwendunglet dbQueue = try DatabaseQueue(path: "/path/to/database.sqlite")try migrator.migrate(dbQueue)Vorteile von GRDB.swift: typisierte Abfragen, Transaktionsunterstützung, einfaches Rückgängigmachen von Migrationen.
3. Realm Swift (jetzt Atlas Device SDK)
Realm verarbeitet die meisten Migrationen automatisch, aber für komplexe Änderungen ist eine explizite Schemaaktualisierung erforderlich.
import RealmSwift
let config = Realm.Configuration( schemaVersion: 2, migrationBlock: { migration, oldSchemaVersion in if oldSchemaVersion < 1 { migration.enumerateObjects(ofType: "User") { oldObject, newObject in newObject?["fullName"] = "\\(oldObject!["firstName"] ?? "") \\(oldObject!["lastName"] ?? "")" } Auch in der Bibliothek
GraphQL-Bibliothek TypeScript: Vollständiger Leitfaden zu den Werkzeugen
E-Mail-Versand mit JavaScript (Node.js): Nodemailer, SendGrid, Mailgun
JSON-Verarbeitung in JavaScript (Node.js): Vollständiger Leitfaden
JWT-Token in Go (Golang): Bibliothek golang-jwt und Anwendungsbeispiele