Skip to content

Latest commit

 

History

History
63 lines (45 loc) · 2.76 KB

migrations.md

File metadata and controls

63 lines (45 loc) · 2.76 KB

Progressive migrations

CoreData has a built-in model-driven data migration engine. But from a product development perspective, these migrations have one major drawback. Since migration is always performed from any version of the storage to the selected (latest), then with each next release of your product, the QA team must check all combinations of migrations. To avoid these difficulties, there is the idea of progressive migrations, when instead of one migration M -> N, you need to carry out N-M migrations: M, M + 1, ..., N-1, N. This approach allows for per-release testing of migrations, i.e. check only N-1 -> N migration. The general algorithm for progressive migrations when working with CoreData is very simple: we find the version of the model that matches the metadata of the existing storage and, step by step, we migrate to the latest available model version. If the storage is not found, then we simply create a new one with the metadata of the latest model version. Of course, in case of updating from very old versions of a product to a fresh one, a situation is possible when there are a lot of migration steps, but this is a tradeoff in order to ensure fast and reliable product releases.

Sworm way

  1. Create model version using Xcode in the usual way:

migrations

  1. Create an instance of SQLiteStoreDescription:
let storeDescription = SQLiteStoreDescription(
    name: "MigratableStore", // just name
    url: <store url>, // file url, where sqlite database is placed
    modelName: "MigratableDataModel", // name of your xcdatamodel
    modelVersions: [
        "V0", // model version without mapping model
        .init(name: "V1", mappingModelName: "V0V1"), // model version with mapping model
        .init(name: "V2", mappingModelName: "V1V2"),
        "V3",
    ]
)
  1. Initialize the migration object:
let migration = try SQLiteProgressiveMigration(
    store: storeDescription,
    bundle: bundle // where to search compiled model versions and mapping models
)
  1. Perform migration:
if let migration = migration {
    print(migration.stepCount)

    try migration.performMigration(progress: <progress closure>)
}

Example

How to use progressive migrations with NSPersistentContainer:

let persistentContainer = try NSPersistentContainer(store: storeDescription, bundle: bundle)
let migration = try SQLiteProgressiveMigration(store: store, bundle: bundle)
try migration?.performMigration(progress: nil)
try persistentContainer.loadPersistentStore()

Links

williamboles.me

objc.io

kean.blog