Swift 数据库迁移:iOS/macOS 工具与实践

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Swift 数据库迁移(iOS/macOS)



开发 iOS 和 macOS 应用时,经常需要处理本地数据库。随着应用的发展,数据结构不可避免地会发生变化:添加新字段、更改类型或删除过时的实体。如果没有正确的迁移机制,这些更改可能导致用户数据丢失或应用崩溃。在本文中,我们将介绍在 Swift 中执行数据库迁移的主要工具和方法,并提供流行解决方案的实用示例。



为什么迁移很重要?

数据库迁移确保:

  • 数据完整性 — 用户记录在模式更新时不会丢失。
  • 向后兼容性 — 应用在旧版本数据上仍能正常运行。
  • 开发灵活性 — 能够迭代更改数据模型而无需手动干预。


Swift 中主要的迁移工具



1. Core Data + NSPersistentContainer

Apple 内置框架提供自动和轻量级迁移。对于复杂更改,则使用手动模型版本控制。

// 配置支持迁移的容器let 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)") }}

对于手动迁移,需要创建模型版本(.xcdatamodeld)和 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 — 现代 SQLite 驱动

GRDB.swift 提供基于步骤注册的灵活迁移机制。迁移按顺序且原子性地执行。

import GRDB

var migrator = DatabaseMigrator()

// 注册第一个迁移migrator.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() }}

// 注册第二个迁移(添加字段)migrator.registerMigration("v2_add_age") { db in try db.alter(table: "users") { t in t.add(column: "age", .integer).defaults(to: 0) }}

// 在应用启动时应用迁移let dbQueue = try DatabaseQueue(path: "/path/to/database.sqlite")try migrator.migrate(dbQueue)

GRDB.swift 的优势:类型化查询、事务支持、简单的迁移回滚。



3. Realm Swift(现为 Atlas Device SDK)

Realm 自动处理大多数迁移,但对于复杂更改,需要显式更新模式。

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

推荐