Как мне декодировать NSDecimalNumber без потери точности?

Есть ли способ сообщить JSONDecoder о преобразовании входящих десятичных знаков в строки?

 public struct Transaction: Decodable
 {
    public let total: NSDecimalNumber?


    enum CodingKeys: String, CodingKey {
        case total = "AMOUNT"

    }

    public init(from decoder: Decoder) throws
    {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        let total = try values.decode(Decimal.self, forKey: .total)
        self.total = NSDecimalNumber(decimal: total);
    }

 }

Подумайте, что произойдет, если СУММА будет выглядеть примерно так: 397289527598234759823475455622342424358363514,42.

Я полагаю, что с кодом, который у меня есть, я бы получил исключение nonConformingFloatDecodingStrategy без возможности восстановления после этого или потери точности.

Борьба вокруг идиотского быстрого Decimal задокументирована повсюду. в частности здесь:

Создание кода NSDecimalNumber


person Anton Tropashko    schedule 28.06.2019    source источник
comment
Вы должны иметь его как String в вашем JSON для начала, иначе он сначала скроет его в Double, а затем в ваш тип.   -  person user28434'mstep    schedule 28.06.2019


Ответы (1)


Проблема в том, что JSONDecoder — это всего лишь оболочка вокруг JSONSerialization, которая внутри декодирует десятичные числа в Double и только после этого преобразует их в Decimal. К сожалению, если вы не создадите собственный декодер JSON, вы не сможете обойти эту проблему при использовании десятичных чисел из JSON.

Единственный возможный обходной путь в настоящее время — это изменить ваш бэкэнд, чтобы он отправлял все десятичные числа как Strings, а затем преобразовывал их в Decimals после декодирования их как Strings.

Для получения дополнительной информации взгляните на эту открытую ошибку Swift: SR-7054.

person Dávid Pásztor    schedule 28.06.2019