Skip to content

Instantly share code, notes, and snippets.

Last active June 7, 2023 06:56
  • Star 37 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
What would you like to do?
Example demonstrating how to use versioning for Codable structs
// This gist demonstrates how you can implement versioning for a Codable struct to support loading
// old serialized data after changing the structure. Notable features of this solution:
// * No need to make new properties optional, or to perform post-processing on the struct after
// loading in ordeer to populate missing values
// * No need to change the call site - from the outside this struct behaves just the same
// as if we had implemented codable directly in the normal way.
// * Versioning can be applied individually to parents or leaves in a larger tree of
// structs without affecting the other elements
// * This approach will work even if the original struct was not designed with versioning in mind
// and was directly serialized without using an intermediate struct.
// Note: In this trivial case you could (and probably would) solve the problem in a simpler way
// without having multiple versions of the serialization struct by just making the `id` property
// optional, but the intention is to demonstrate how to handle an arbitrarily complex change.
import Foundation
struct User {
var name: String
var id: String
extension User: Codable {
// V1 used email instead of opaque id
private struct UserV1: Decodable {
let name: String
let email: String
// V2 matches current implementation
private struct UserV2: Decodable {
let name: String
let id: String
init(from decoder: Decoder) throws {
do {
let userV2 = try UserV2(from: decoder)
self.init(name:, id:
} catch {
let userV1 = try UserV1(from: decoder)
self.init(name:, id:
let oldJSON = """
"name": "Foo Bar",
"email": ""
let data = .utf8)!
let user = try! JSONDecoder().decode(User.self, from: data)
print(user) // User(name: "Foo Bar", id: "")
Copy link

jkalias commented Jul 14, 2021

Typo in line 5
loading in ordeer to populate missing values

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