Migrações de banco de dados em Swift: ferramentas e práticas para iOS/macOS

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Migrações de banco de dados em Swift (iOS/macOS)



O desenvolvimento de aplicativos para iOS e macOS frequentemente exige trabalho com bancos de dados locais. À medida que o aplicativo evolui, a estrutura de dados inevitavelmente muda: novos campos são adicionados, tipos são alterados ou entidades obsoletas são removidas. Sem um mecanismo adequado de migrações, essas alterações podem levar à perda de dados do usuário ou à falha do aplicativo. Neste artigo, abordaremos as principais ferramentas e abordagens para realizar migrações de banco de dados em Swift, além de fornecer exemplos práticos para soluções populares.



Por que as migrações são importantes?

As migrações de banco de dados garantem:

  • Preservação de dados — os registros do usuário não são perdidos ao atualizar o esquema.
  • Compatibilidade reversa — o aplicativo continua funcionando em versões antigas dos dados.
  • Flexibilidade de desenvolvimento — possibilidade de alterar iterativamente o modelo de dados sem intervenção manual.


Principais ferramentas para migrações em Swift



1. Core Data + NSPersistentContainer

O framework integrado da Apple fornece migrações automáticas e leves. Para alterações complexas, utiliza-se versionamento manual do modelo.

// Configuração do contêiner com suporte a migraçõeslet 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)") }}

Para migração manual, são criadas versões do modelo (.xcdatamodeld) e NSMappingModel:

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 — driver SQLite moderno

O GRDB.swift oferece um mecanismo flexível de migrações baseado no registro de etapas. As migrações são executadas sequencialmente e atomicamente.

import GRDB

var migrator = DatabaseMigrator()

// Registro da primeira migraçãomigrator.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() }}

// Registro da segunda migração (adição de campo)migrator.registerMigration("v2_add_age") { db in try db.alter(table: "users") { t in t.add(column: "age", .integer).defaults(to: 0) }}

// Aplicação das migrações na inicialização do aplicativolet dbQueue = try DatabaseQueue(path: "/path/to/database.sqlite")try migrator.migrate(dbQueue)

Vantagens do GRDB.swift: consultas tipadas, suporte a transações, reversão simples de migrações.



3. Realm Swift (agora Atlas Device SDK)

O Realm lida automaticamente com a maioria das migrações, mas para alterações complexas é necessária uma atualização explícita do esquema.

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"] ?? "")" }

Recommendations