Мой декодер JSON не работает, и я не уверен, почему

#json #swift #decodable

#json #swift #декодируемый

Вопрос:

Я пытаюсь получить доступ к вложенной переменной JSON с именем ‘block’, но, похоже, я не могу получить к ней доступ ни одним из способов, которые я пробовал. Вот пример JSON-сообщения и мой код:

{«account»:»xrb_34tsctqcgctm8fhnpat351z4f64rgz8o9y7gwh1dutjf1r7iiwfzruawhatz»,»hash»:»E5935C559748444D09E97D6D13FDB48B51F46A01FA9F6FB2DBD3576D684A53C6″,»block»:»{ n «тип «: «состояние «,n «учетная запись «: «xrb_34tsctqcgctm8fhnpat351z4f64rgz8o9y7gwh1dutjf1r7iiwfzruawhatz «,n «предыдущий «: «78446816869EEEF4BC735B1A21AB33ED246A10303B87F0CAFD7CCD56406E0456», «представитель»: «xrb_3pczxuorp48td8645bs3m6c3xotxd3idskrenmi65rbrga5zmkemzhwkaznh» ,n «баланс»: «320000000000000000000000000», n»ссылка»: «8DE4EE799910E26C5E44CDD345B8C8070E1955284BC407660825B425FBEDBB6B», n «link_as_account»: «xrb_35h6xswsk694fjh6bmgmapwei3rg57ckiky61xm1ibfn6qxyugud9eo1fauk», n «подпись «: «E4AF5BBDF583509DF3147004AB61FEC04F9007AC23A46A2E2E5BE4B65D0788F45F89EEC7B62D0F42144A9F5EA090EF3F58262070F07C59F1AD752B5CC3BF9D04», n «работа «: «a56cb9e8d2539f73″n}n»,»сумма»: «1`

 struct IncomingBlock: Decodable {
    var account: String
    var hash: String

    struct Block: Decodable {
        var type: String
        var previous: String
        var link: String
        var link_as_account: String
        var representative: String
        var account: String
        var balance: String
        var work: String
        var signature: String
    }

    var block: Block
}

// in another file
guard let data = msg.data(using: .utf8) else { return }
guard let incomingBlock = try?JSONDecoder().decode(IncomingBlock.self, from: data) else { return }
  

Комментарии:

1. Покажите вашу попытку доступа к данным. Но сначала измените try? на try внутри a do/catch , где вы делаете print(error) внутри catch . Тогда вы будете знать любую ошибку, а не игнорировать ее.

2. Ваш block контент, похоже, имеет двойное кодирование, что часто встречается в API, разработанном плохими инженерами на стороне сервера. Скажите инженеру на стороне сервера, чтобы API возвращал JSON без двойного кодирования. Или вам может потребоваться декодировать его как строку и повторно декодировать как JSON.

3. вы можете написать пользовательский декодер инициализации, чтобы справиться с этим на данный момент, или лучше изменить свой ответ

4. Если ошибки нет, то в чем вопрос? И просто печатайте error , а не error.localizedDescription . Вы увидите более подробную информацию.

5. Что вы пытались? Что-то сказать инженеру на стороне сервера? Я предложил повторно декодировать, ничего похожего на приведение к Any или AnyObject .

Ответ №1:

По сути, для доступа к вложенной JSON переменной block мне пришлось декодировать исходное JSON сообщение

 do{
  guard let data = inital_msg.data(using: .utf8) else { return }
  let incomingBlock = try JSONDecoder().decode(IncomingBlock.self, from: data) 
catch ...{}
  

и приведите значение block s к строке в модели.

 struct IncomingBlock: Decodable {
var account: String
var hash: String
var block: String
}
  

После этого я еще block раз декодировал начальное поле сообщений следующим образом

// Второй JSON

 let json = incomingBlock.block.data(using: .utf8)!
  

наконец, с разделенной блочной моделью:

  struct BlockMeta: Decodable {
    var type: String
    var previous: String
    var link: String
    var link_as_account: String
    var representative: String
    var account: String
    var balance: String
    var work: String
    var signature: String
 }
  

Я мог получить доступ к полям

  let block = try JSONDecoder().decode(BlockMeta.self, from: json)
 block.balance //returns "320000000000000000000000000"