Created
May 5, 2020 09:52
-
-
Save earltedly/bbd50e9bbc00bebdb76e66e060e650bc to your computer and use it in GitHub Desktop.
Versioning
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.