Durante varias horas no puedo entender qué está mal con mi código. Revisé mi código e Internet muchas veces, pero no encontré nada realmente útil. Mi problema es que uso la API de finnhub.io para obtener un JSON que luego quiero decodificar correctamente. Todo funciona bien, excepto la decodificación que se encuentra con un error. Consulte el código a continuación, tal vez pueda darme una pista, realmente no tengo ideas.

La JSON que obtengo:

[{u'date': u'2019-11-07', u'symbol': u'AAPL', u'amount': 0.77}, {u'date': u'2019-08-09', u'symbol': u'AAPL', u'amount': 0.77}, {u'date': u'2019-05-10', u'symbol': u'AAPL', u'amount': 0.77}, {u'date': u'2019-02-08', u'symbol': u'AAPL', u'amount': 0.73}]

Mi código SWIFT se ve así:

import SwiftUI

struct Dividends: Decodable {
    let dividend: Dividend
}

struct Dividend: Decodable {
    let date: String
    let symbol: String
    let amount: String
}

let json = """
{
    "date": "2000-01-01",
    "symbol": "AAPL",
    "amount": "0.0"
}
""".data(using: .utf8)!

struct ContentView: View {

    var body: some View {
        Text("Text")
        .onAppear(perform: loadData)
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

func loadData() {
    let jsonData = json

    let url = URL(string: "https://finnhub.io/api/v1/stock/dividend?symbol=AAPL&from=2010-01-01&to=2020-12-31&token=xxx")!
    let urlSession = URLSession.shared
    let task = urlSession.dataTask(with: url) { data, response, error in

        let dividends: [Dividend] = try! JSONDecoder().decode([Dividend].self, from: jsonData)

        for dividend in dividends {
            print(dividend.symbol)
            print(dividend.date)
            print(dividend.amount)
        }
    }

    // data task needs to be started explicitly via resume
    task.resume()
}

Y el mensaje de error que recibo al ejecutar la aplicación es:

Fatal error: 'try!' expression unexpectedly raised an error: Swift.DecodingError.typeMismatch(Swift.Array<Any>, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Array<Any> but found a dictionary instead.", underlyingError: nil)): file /Users/joe/Desktop/LoadJSON/LoadJSON/ContentView.swift, line 50
2020-04-25 14:02:33.682895+0200 LoadJSON[2347:102791] Fatal error: 'try!' expression unexpectedly raised an error: Swift.DecodingError.typeMismatch(Swift.Array<Any>, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Array<Any> but found a dictionary instead.", underlyingError: nil)): file /Users/joe/Desktop/LoadJSON/LoadJSON/ContentView.swift, line 50

Por lo que veo, mi JSON es una matriz con elementos de diccionario, pero no puedo decodificarlo correctamente. ¿Mi código está realmente tan mal?

-2
Joe 25 abr. 2020 a las 15:10

2 respuestas

Debes corregir tu json de prueba como se muestra a continuación,

let json = """
[
{
    "date": "2000-01-01",
    "symbol": "AAPL",
    "amount": "0.0"
},
{
    "date": "2000-01-01",
    "symbol": "AAPL",
    "amount": "0.0"
}
]
""".data(using: .utf8)!

O use el data real devuelto por la API como,

let dividends: [Dividend] = try! JSONDecoder().decode([Dividend].self, from: data!)
0
Kamran 25 abr. 2020 a las 12:35

Su JSON debería verse así:

let json = """
"Something" : [
{
    "date": "2000-01-01",
    "symbol": "AAPL",
    "amount": "0.0"
},
{
    "date": "2000-01-01",
    "symbol": "AAPL",
    "amount": "0.0"
}
]

""".data(using: .utf8)!
0
george 25 abr. 2020 a las 12:27