Swiftpack.co - JanGorman/Waxwing as Swift Package

Swiftpack.co is a collection of thousands of indexed Swift packages. Search packages.
See all packages published by JanGorman.
JanGorman/Waxwing 5.0.1
iOS version migrations 🦤
⭐️ 7
🕓 1 week ago
.package(url: "https://github.com/JanGorman/Waxwing.git", from: "5.0.1")

Build Status codecov Carthage compatible SPM Version License Platform


iOS version migrations in Swift. When mangling data or performing any other kind of updates you want to ensure that all relevant migrations are run in order and only once. Waxwing allows you to do just that.


  • Swift 5
  • iOS 8+



Waxwing is available through CocoaPods. To install add the following line to your Podfile:

pod "Waxwing"


If you don't like CocoaPods, you can add the dependency via Carthage or include Waxwing.swift in your project.

Swift Package Manager

You can use the Swift Package Manager to install Waxwing by adding it to your Package.swift file:

import PackageDescription

let package = Package(
    name: "YOUR_PROJECT_NAME",
    targets: [],
    dependencies: [
        .Package(url: "https://github.com/JanGorman/Waxwing", majorVersion: 5),


There are two ways to run your migrations, either with closures or through an OperationQueue:

import Waxwing


let waxwing = Waxwing(bundle: .main, defaults: .standard)

waxwing.migrateToVersion("0.9") {


import Waxwing

let waxwing = Waxwing()

Waxwing.migrateToVersion("0.9", [FirstMigrationClass(), SecondMigrationClass()])

Note that closure based migrations are run from the thread they are created on. Anything that has to run on the main thread, such as notifying your users of changes introduced with this version, needs to explictly call the method on the main thread:

import Waxwing

DispatchQueue.global().async {
  let waxwing = Waxwing(bundle: .main, defaults: .standard)
  waxwing.migrateToVersion("0.9") {
    DispatchQueue.main.async {
      // Some alert that we're done updating / what's new in this version of the app

The OperationQueue based migrations are always run from their own queue so the same caveat applies. Also note, that if any of the migrations in the queue depend on another one having run first, you explicitly need to add that dependency. Operation makes this trivial through the addDependency() method.

You can add as many migrations as you want. They will only ever be executed once.


Waxwing has built in support for Progress. Since the number of actions that are run using the closure based method cannot be determined it just reports a total unit count of 1. If you're using operations, the unit count will match the number of migrations.

import Waxwing

func migrate() {
  let progress = Progress(totalUnitCount: 1)
  progress.becomeCurrent(withPendingUnitCount: 1)
  _ = progress.observe(\.fractionCompleted, options: [.new]) { progress, _ in
    // e.g. Update progress indicator, remember to do this on the main thread
  waxwing.migrateToVersion("0.8", migrations: [migration1, migration2, migration3…])

For more information on how Progress works I recommend this article by Ole Begemann.


Jan Gorman


Waxwing is available under the MIT license. See the LICENSE file for more info.


Stars: 7
Last commit: 1 week ago
Advertisement: IndiePitcher.com - Cold Email Software for Startups

Release Notes

SPM Support
3 years ago
  • Support fro SPM. Thanks @LambdaDigamma for the addition

Swiftpack is being maintained by Petr Pavlik | @ptrpavlik | @swiftpackco | API | Analytics