Restore

Build Code Coverage Release Swift Version License

Take a snapshot of an object and restore from it.

Read the full documentation here

Restore is a convenient, easy to use package that allows you to snapshot the state of an object for later restoration. Start by creating a type that conforms to the RestorableObject protocol, and decorating the properties you wish to include in snapshots with the Restorable property wrapper.

class FavoriteFruits: RestorableObject {
    @Restorable var rank1 = "Apple"
    @Restorable var rank2 = "Banana"
    @Restorable var rank3 = "Watermelon"
}
let favorites = FavoriteFruits()

Let’s say that somewhere down the line, “Banana” overtakes “Apple”, moving into rank1. As an extra precaution, the judges want to save the current results in case a mistake was made. They do so using the RestorableObject/takeSnapshot(withKey:) method. Now they are free to update the results.

favorites.takeSnapshot(withKey: "BackupResults")

favorites.rank1 = "Banana"
favorites.rank2 = "Apple"

Later, they find out that a mistake was indeed made. The vote was miscounted, and the results are now invalid. Thankfully, they have the backup. Rather than having to go through each individual property and set their values back to their original states, they can simply call the RestorableObject/restore(withKey:) method. Every property is set back to the way it was before the mistake was made. Crisis averted.

favorites.restore(withKey: "BackupResults")

print(favorites.rank1) // Prints "Apple"
print(favorites.rank2) // Prints "Banana"

Now, let’s say that the judges get a fancy new Counter object. It automatically tallies the results and stores them within itself. But they still want the people viewing the results to be able to access the results from the counter. To do this, they must use a computed property.

class FavoriteFruits: RestorableObject {
    let counter = Counter()
    
    var rank1: String { 
        counter.rank1 
    }
    var rank2: String {
        counter.rank2
    }
    var rank3: String {
        counter.rank3
    }
}

This poses a problem, however, as computed properties don’t support property wrappers. Now they can’t mark their ranks as Restorable. Then one of the judges, who read the manual, remembered that they can add computed properties to the RestorableObject/references-4bbzk array, and they will still be included in snapshots and restorations. Again, crisis averted.

class FavoriteFruits: RestorableObject {
    let counter = Counter()

    var rank1: String { 
        counter.rank1 
    }
    var rank2: String {
        counter.rank2
    }
    var rank3: String {
        counter.rank3
    }
    
    var references: [Reference<FavoriteFruits>] {
        Reference(owner: self, name: "rank1", keyPath: \.rank1)
        Reference(owner: self, name: "rank2", keyPath: \.rank2)
        Reference(owner: self, name: "rank3", keyPath: \.rank3)
    }
}

The name parameter in the Reference type’s initializer must be the same as the name of the property, or the property will not be saved.

GitHub

View Github