I have a Measurement<UnitMass> object that I want to store in NSUbiquitousKeyValueStore. I use Measurement because I need to convert values between various locale on a regular basis.
I have tried extending Measurement. I imagine there are more than one problem with the code below but the place I got stuck at was how to deal with UnitMass or UnitType conversion. (I would prefer if I could use UnitType in the code, so I could reuse it for other measurements.
extension Measurement {
init(data: NSData) {
let coding = try? NSKeyedUnarchiver.unarchivedObject(ofClass: Coding.self, from: data as Data)
self.value = coding?.value as! Double
self.unit = coding.unit as UnitMass
}
func asData() -> NSData {
return try! NSKeyedArchiver.archivedData(withRootObject: Coding(self), requiringSecureCoding: true) as NSData
}
class Coding: NSObject, NSCoding {
func encode(with coder: NSCoder) {
coder.encode(value, forKey: "value")
coder.encode(unit, forKey: "unit")
}
let value: NSDecimalNumber
let unit: NSObject
init(_ measurement: Measurement) {
value = NSDecimalNumber(value: measurement.value)
unit = measurement.unit
}
required init?(coder aDecoder: NSCoder) {
self.value = aDecoder.decodeObject(forKey: "value") as! NSDecimalNumber
self.unit = aDecoder.decodeObject(forKey: "unit") as! NSObject
}
}
}
Of course, my first attempt was to simply store.set(weightAsMeasurement, forKey: "weight") and then store.object(forKey: "Weight") as? Measurement<UnitMass> but, of course, the compiler has no idea how to decode that.
I've also considered storing the value and unit separately. Again, I got stuck at the unit.
Any advice welcome.
Edit:
For the time being, I decided to store only the value:
- Convert the measurement to an explicit unit using
.converted(to: .kilogram)(I used kilograms). - Store only the value using
convertedMeasurement.value.
When reading from the store:
- Use ‘store.double(forKey: “weight”)` to read the value from the store.
- Initialize the measurement for the explicitly selected unit using
Measurement(value: value, unit: UnitMass.kilogram)(or whatever unit was used when saving to the store). - Convert the measurement to the current locale using
measurementInKilogram.converted(to: Locale.current)
Is there a better way to do it?
Measurementconforms toCodable, just useJSONEn-/Decoder