Question or problem in the Swift programming language:
I’ve created a “codable” struct to serialize a data set and encode it to Json. Everything is working great except the computed properties don’t show in the json string. How can I include computed properties during the encode phase.
Ex:
struct SolidObject:Codable{ var height:Double = 0 var width:Double = 0 var length:Double = 0 var volume:Double { get{ return height * width * length } } } var solidObject = SolidObject() solidObject.height = 10.2 solidObject.width = 7.3 solidObject.length = 5.0 let jsonEncoder = JSONEncoder() do { let jsonData = try jsonEncoder.encode(solidObject) let jsonString = String(data: jsonData, encoding: .utf8)! print(jsonString) } catch { print(error) }
prints out “{“width”:7.2999999999999998,”length”:5,”height”:10.199999999999999}”
I am also curious about having 7.29999.. instead of 7.3 but my main question is “how can I include “volume” to this json string too”?
How to solve the problem:
You need to manually encode/decode instead of letting the automated stuff do it for you. This works as expected in a Swift playground.
struct SolidObject: Codable { var height:Double = 0 var width:Double = 0 var length:Double = 0 var volume:Double { get{ return height * width * length } } enum CodingKeys: String, CodingKey { case height case width case length case volume } init() { } init(from decoder: Decoder) throws { let values = try decoder.container(keyedBy: CodingKeys.self) height = try values.decode(Double.self, forKey: .height) width = try values.decode(Double.self, forKey: .width) length = try values.decode(Double.self, forKey: .length) } func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(height, forKey: .height) try container.encode(width, forKey: .width) try container.encode(length, forKey: .length) try container.encode(volume, forKey: .volume) } } var solidObject = SolidObject() solidObject.height = 10.2 solidObject.width = 7.3 solidObject.length = 5.0 let jsonEncoder = JSONEncoder() do { let jsonData = try jsonEncoder.encode(solidObject) let jsonString = String(data: jsonData, encoding: .utf8)! print(jsonString) } catch { print(error) }