Migrations de bases de données en Swift (iOS/macOS)
Le développement d'applications pour iOS et macOS nécessite souvent de travailler avec des bases de données locales. Au fur et à mesure que l'application évolue, la structure des données change inévitablement : de nouveaux champs sont ajoutés, les types sont modifiés ou des entités obsolètes sont supprimées. Sans un mécanisme de migration approprié, ces changements peuvent entraîner une perte de données utilisateur ou un plantage de l'application. Dans cet article, nous examinerons les principaux outils et approches pour effectuer des migrations de bases de données en Swift, et nous fournirons des exemples pratiques pour les solutions populaires.
Pourquoi les migrations sont-elles importantes ?
Les migrations de bases de données assurent :
- La préservation des données — les enregistrements utilisateur ne sont pas perdus lors de la mise à jour du schéma.
- La rétrocompatibilité — l'application continue de fonctionner sur les anciennes versions des données.
- La flexibilité du développement — la possibilité de modifier itérativement le modèle de données sans intervention manuelle.
Principaux outils pour les migrations en Swift
1. Core Data + NSPersistentContainer
Le framework intégré d'Apple fournit des migrations automatiques et légères. Pour les modifications complexes, un versionnement manuel du modèle est utilisé.
// Configuration du conteneur avec prise en charge des migrationslet 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)") }}Pour la migration manuelle, des versions du modèle (.xcdatamodeld) et NSMappingModel sont créées :
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 — pilote SQLite moderne
GRDB.swift offre un mécanisme de migration flexible basé sur l'enregistrement d'étapes. Les migrations sont exécutées séquentiellement et atomiquement.
import GRDB
var migrator = DatabaseMigrator()
// Enregistrement de la première 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() }}
// Enregistrement de la deuxième migration (ajout d'un champ)migrator.registerMigration("v2_add_age") { db in try db.alter(table: "users") { t in t.add(column: "age", .integer).defaults(to: 0) }}
// Application des migrations au démarrage de l'applicationlet dbQueue = try DatabaseQueue(path: "/path/to/database.sqlite")try migrator.migrate(dbQueue)Avantages de GRDB.swift : requêtes typées, prise en charge des transactions, annulation simple des migrations.
3. Realm Swift (maintenant Atlas Device SDK)
Realm gère automatiquement la plupart des migrations, mais pour les modifications complexes, une mise à jour explicite du schéma est nécessaire.
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"] ?? "")" } Aussi dans la bibliothèque
Validation des données en Rust : bibliothèques et approches pour un code fiable
Jetons JWT en Kotlin : Guide complet avec exemples de code
Rate Limiting en Kotlin : bibliothèques et exemples pratiques
Mikro-ORM TypeScript : guide complet avec exemples
Cryptographie en TypeScript : Aperçu de la bibliothèque crypto-js