I did wrote some code to save some struct to disk in JSON format.
However, if I save it in a variable and keep that and use it to decoded it then the UUID’s are different.
import Foundation
import PlaygroundSupport
import Swift
struct Project: Codable, Identifiable, Hashable {
let id: UUID = UUID()
let id2: String = UUID().uuidString
let name: String
}
let project = Project(name: "PP50")
let encodedData = try JSONEncoder().encode(project)
let jsonString = String(data: encodedData,
encoding: .utf8)
print(project.id)
print(project.id2)
print(project.name)
print(jsonString)
print("===================")
if let dataFromJsonString = jsonString?.data(using: .utf8) {
let projectFromData = try JSONDecoder().decode(Project.self, from: dataFromJsonString)
print(projectFromData)
print(projectFromData.name)
print(projectFromData.id) // <<< why is the id and id'2 different
print(projectFromData.id2)
}
The result is:
826FEC8A-7FE0-4E6C-8DC1-A0DFA4FC75BE
2D15A1B8-B936-4829-8DC2-9C44B261712E
PP50
Optional("{"id":"826FEC8A-7FE0-4E6C-8DC1-A0DFA4FC75BE","id2":"2D15A1B8-B936-4829-8DC2-9C44B261712E","name":"PP50"}")
===================
Project(id: E951D459-3C0E-43A3-B9C6-2CCF2EB1AEE3, id2: "3C97B5C3-054D-4372-800D-9210439F48C2", name: "PP50")
PP50
E951D459-3C0E-43A3-B9C6-2CCF2EB1AEE3
3C97B5C3-054D-4372-800D-9210439F48C2
Maybe a simple answer, but I don’t see it yet.
Why is the outcome of the id different then the one created?
How come? How to solve this?
3
Answers
All you need to do is to
var
declare yourid
properties and they will be included in the decodingWhen you create an instance of
Project
,id
andid2
are constants that get default values fromUUID()
– you can’t modify these values when decoding a JSON.id
andid2
need to be variables (var
), not constants (let
). By doing this, the values can be modified by the JSON contents.As others have said in comments and other answers,
let
properties declared with initial values are not decoded and the default value will be used. In this case, the default is a new UUID.Changing the properties to
var
will include them in decoding, even with the default values. However, since identifiers probably shouldn’t be mutable, an implementation which keeps the properties aslet
but has the same externally visible API is to use an explicit initialiser to provide the default values:By providing default values in the initialiser, a
Project
can still be created with just a name. Since the properties themselves do not have an initialiser, they will be decoded.