#json #swift #xcode #measurement
Вопрос:
Я создал структуру для хранения некоторых измерений. Структура соответствует кодируемому протоколу, поэтому я могу хранить структуры в JSON. Измерения могут иметь различные единицы измерения, поэтому я использовал Measurement<Dimension>
.
При извлечении данных с диска я не могу использовать измерения, потому что они возвращаются как размер, и я, похоже, не могу выяснить, какая у них единица измерения (например, масса единицы, длина единицы и т. Д.). Это важно в приложении, потому что может потребоваться преобразовать измерения из метрических в имперские единицы (например, преобразовать кг в фунты и т. Д.).
Вот краткий пример кода, иллюстрирующий проблему:
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."
Печать единицы измерения перед кодированием JSON дает что-то вроде этого: <_NSStatic_NSUnitMass: 0x7fff801f8888> lb
после декодирования JSON это <NSDimension: 0x600001c05480> lb
(для измерения в фунтах). Таким образом, символ остается нетронутым, но что-то изменилось в типе единицы измерения.
Чтобы исправить эту проблему, я написал процедуру для ручного назначения правильных типов единиц декодированным структурам в соответствии с правильно сохраненным символом, но это решение кажется слишком сложным и подверженным ошибкам.
Есть идеи, как решить эту проблему более элегантно? Как всегда, большое вам спасибо за ваши мысли!
Комментарии:
1. Если это сделать
print(result.x.value)
, иprint(result.x.unit.symbol)
вы увидите, что x равен 1 кг, который вы использовали при создании объекта, так что все так, как должно быть.2. Я думаю, что проблема здесь в том, что никто не обещал, что эта единица будет кодируемой, и на самом деле это не так. Возможно, было бы полезно спросить, почему вы хотите явно говорить о типе измерения.
3. Привет, Мэтт, спасибо, что подумал над моим вопросом. Я хочу сохранить небольшую базу данных измерений. Хранение данных в JSON казалось самым простым решением.
4. Я отредактировал вопрос, чтобы уточнить, почему мне нужно знать подкласс измерения в приложении.