#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
внутри ado/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"