Skip to content

Instantly share code, notes, and snippets.

@earltedly
Created May 5, 2020 09:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save earltedly/bbd50e9bbc00bebdb76e66e060e650bc to your computer and use it in GitHub Desktop.
Save earltedly/bbd50e9bbc00bebdb76e66e060e650bc to your computer and use it in GitHub Desktop.
Versioning
import Foundation
// Version 1
struct Version: Codable {
let name: String
}
// This is a compacted JSON string of version 1
let encoded = try! JSONEncoder().encode(Version1(name: "Hello"))
// Version 2, failing attempt
struct Version: Codable {
let name: String
let windSpeed: Int
}
// Fails because the previous version does not have a `windSpeed` key
let decoded = try! JSONDecoder().decode(Version.self, from: encoded)
// Version 2, with a default
struct Version: Codable {
let name: String
let windSpeed: Int = 0
}
// Works, windSpeed = 0
let decoded = try! JSONDecoder().decode(Version.self, from: encoded)
// Version 2, with optional value
struct Version: Codable {
let name: String
let windSpeed: Int?
}
// Works, windSpeed = nil
let decoded2 = try! JSONDecoder().decode(Version.self, from: encoded)
// A last strategy if you make a big change
// First we snapshot the last version and give it a number
struct Version1: Codable {
let name: String
}
struct Version: Codable {
let aNewKindOfName: String
}
extension Version {
init(version1: Version1) {
self.init(aNewKindOfName: version1.name)
}
}
// Try version first and fallback to version1 if it doesn't work
do {
decoded = try JSONDecoder().decode(Version.self, from: encoded)
} catch {
do {
version1 = try JSONDecoder().decode(Version1.self, from: encoded)
decoded = Version(version1: version1)
} catch {
// we'd not nest all these
}
}
@earltedly
Copy link
Author

My last example is a bit simplistic. You could instead define CodingKeys and capture the rename in there, but it's going to remain that name in output file.

You could also do a custom init(from decoder: Decoder) throws and then put any migration logic in per key.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment