I have created a struct to store some measurements. The struct conforms to the codable protocol so I can store the structs in a JSON. The measurements can have various units, so I used
Measurement<Dimension>.
When retrieving the data from the disk I can't use the measurements because they are returned as Dimension and I can't seem to find out, what kind of unit they have (e.g. UnitMass, UnitLength etc.). This is important in the app, because it might be necessary to convert measurements from metric to imperial units (e.g. convert kg to pounds etc.).
Here is a short code-sample to illustrate the problem:
struct StatisticalValues: Codable {
var x: Measurement<Dimension>?
var l: Double?
var m: Double?
var s: Double?
}
var test = StatisticalValues(x: Measurement(value: 1.0, unit: UnitMass.kilograms), l: 1.0, m: 2.0, s: 3.0)
// after coding as a JSON and decoding I try to find out the Unit of Dimension with this code
if let testUnit = test.x?.unit {
switch testUnit {
case is UnitMass: print("test is UnitMass")
case is UnitLength: print("test is UnitLength")
default: print("test is another unit")
}
}
// this returns always the default case, even though the stored unit was a UnitMass
if let testX = test.x {
let convertedX = testX.converted(to: UnitMass.pounds)
}
// gives an error:
// "*** You must override baseUnit in your class NSDimension to define its base unit."
Printing the unit before the JSON coding gives something like this: <_NSStatic_NSUnitMass: 0x7fff801f8888> lb after decoding the JSON it's <NSDimension: 0x600001c05480> lb (for a measurement in pounds). So the symbol is kept intact, but something has changed about the unit type.
To correct this problem I've written a routine to manually assign the correct unit types to the decoded structs, according to the correctly stored symbol, but this solution seems overly complicated and error prone.
Any ideas how to solve this more elegantly? As always thank you so much for your thoughts!