Swift: Сохранение измерений в формате JSON

#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. Я отредактировал вопрос, чтобы уточнить, почему мне нужно знать подкласс измерения в приложении.