简体   繁体   中英

How can I parse this nested JSON? - error

The main objective is to parse a local json file into a list of "subjects", and then get access to the questions and options inside each "subject" in one Json, in orden to just add one file to the app and not a file for each subject

I AM TRYING TO DECODE A NESTED JSON LIKE THIS:

[{
    "id": 1,
    "nTema": "1",
    "tema": "TEMA 1",
    "imageName": "T1",
    "cantidadPreguntas": "3",
    "preguntas": [{
            "id": 1,
            "nPregunta": "1",
            "ePregunta": "TEMA 1 ENUNCIADO 1",
            "opcionA": "T1 P1 OPCION A",
            "opcionB": "T1 P1 OPCION B",
            "opcionC": "T1 P1 OPCION C",
            "opcionD": "T1 P1 OPCION D",
            "opcionE": "T1 P1 OPCION E",
            "rPregunta": "opcionA"
        },
        {
            "id": 2,
            "nPregunta": "2",
            "ePregunta": "TEMA 1 ENUNCIADO 2",
            "opcionA": "T1 P2 OPCION A",
            "opcionB": "T1 P2 OPCION B",
            "opcionC": "T1 P2 OPCION C",
            "opcionD": "T1 P2 OPCION D",
            "opcionE": "T1 P2 OPCION E",
            "rPregunta": "opcionB"
        },
        {
            "id": 3,
            "nPregunta": "3",
            "ePregunta": "TEMA 1 ENUNCIADO 3",
            "opcionA": "T1 P3 OPCION A",
            "opcionB": "T1 P3 OPCION B",
            "opcionC": "T1 P3 OPCION C",
            "opcionD": "T1 P3 OPCION D",
            "opcionE": "T1 P3 OPCION E",
            "rPregunta": "opcionC"
        }
    ]
}, {
    "id": 2,
    "nTema": "2",
    "tema": "TEMA 2",
    "imageName": "T2",
    "cantidadPreguntas": "3",
    "preguntas": [{
            "id": 1,
            "nPregunta": "1",
            "ePregunta": "TEMA 2 ENUNCIADO 1",
            "opcionA": "T2 P1 OPCION A",
            "opcionB": "T2 P1 OPCION B",
            "opcionC": "T2 P1 OPCION C",
            "opcionD": "T2 P1 OPCION D",
            "opcionE": "T2 P1 OPCION E",
            "rPregunta": "opcionA"
        },
        {
            "id": 2,
            "nPregunta": "2",
            "ePregunta": "TEMA 2 ENUNCIADO 2",
            "opcionA": "T2 P2 OPCION A",
            "opcionB": "T2 P2 OPCION B",
            "opcionC": "T2 P2 OPCION C",
            "opcionD": "T2 P2 OPCION D",
            "opcionE": "T2 P2 OPCION E",
            "rPregunta": "opcionB"
        },
        {
            "id": 3,
            "nPregunta": "3",
            "ePregunta": "TEMA 2 ENUNCIADO 3",
            "opcionA": "T2 P3 OPCION A",
            "opcionB": "T2 P3 OPCION B",
            "opcionC": "T2 P3 OPCION C",
            "opcionD": "T2 P3 OPCION D",
            "opcionE": "T2 P3 OPCION E",
            "rPregunta": "opcionC"
        }
    ]
}]

THE STRUCTURE I AM USING:

import SwiftUI

struct TemasParametros: Codable, Identifiable {
    var id: Int
    var nTema: String
    var tema: String
    var imageName: String
    var cantidadPreguntas : String
    var preguntas : **[PreguntasParametros]**


    struct **PreguntasParametros**: Codable, Identifiable {
        var id: Int
        var nPregunta: String
        var ePregunta: String
        var opcionA: String
        var opcionB: String
        var opcionC: String
            var opcionD: String
            var opcionE: String
            var rPregunta: String

    }
}

extension TemasParametros {
    var image: Image {
        ImageStore.shared.image(name: imageName)
    }
}

struct TemasParametros_Previews: PreviewProvider {
    static var previews: some View {
        Text("TemasParametros")
    }
}

BUT I CANNOT GET ACCESS TO VALUES LIKE:

  • TemasParametros.PreguntasParametros.ePregunta

or

  • TemasParametros.PreguntasParametros.opcionA

TO DECODE I HAVE:

import UIKit
import SwiftUI

let temasData: [TemasParametros] = load("JSONTemas2.json")

func load<T: Decodable>(_ filename: String) -> T {
    let data: Data

    guard let file = Bundle.main.url(forResource: filename, withExtension: nil)
        else {
            fatalError("Couldn't find \(filename) in main bundle.")
    }

    do {
        data = try Data(contentsOf: file)
    } catch {
        fatalError("Couldn't load \(filename) from main bundle:\n\(error)")
    }

    do {
        let decoder = JSONDecoder()
        return try decoder.decode(T.self, from: data)
    } catch {
        fatalError("Couldn't parse \(filename) as \(T.self):\n\(error)")
    }
}

final class ImageStore {
    typealias _ImageDictionary = [String: CGImage]
    fileprivate var images: _ImageDictionary = [:]

    fileprivate static var scale = 2

    static var shared = ImageStore()

    func image(name: String) -> Image {
        let index = _guaranteeImage(name: name)

        return Image(images.values[index], scale: CGFloat(ImageStore.scale), label: Text(name))
    }

    static func loadImage(name: String) -> CGImage {
        guard

            let url = Bundle.main.url(forResource: name, withExtension: "png"),
            let imageSource = CGImageSourceCreateWithURL(url as NSURL, nil),
            let image = CGImageSourceCreateImageAtIndex(imageSource, 0, nil)
            else {
                fatalError("Couldn't load image \(name).png from main bundle.")
        }
        return image
    }

    fileprivate func _guaranteeImage(name: String) -> _ImageDictionary.Index {
        if let index = images.index(forKey: name) { return index }

        images[name] = ImageStore.loadImage(name: name)
        return images.index(forKey: name)!
    }
}

struct TemasData_Previews: PreviewProvider {
    static var previews: some View {
        /*@START_MENU_TOKEN@*/Text("Hello, World!")/*@END_MENU_TOKEN@*/
    }
}

THE ERROR I GET

THE ERROR

TRYING TO SOLVE BUT WITHOUT RESULTS

you have 2 members in the struct StudyTemaCreation that are not initialized (temasparametros and access) you must give value for these members when calling the initializer of the struct (line 34 in the error image)

or you can remove line 15 (I think you don't need it), you can just access temasparametros.preguntas...

for example you can write in line 25:

Text(temasparametros.preguntas[0].ePregunta)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM