Tengo dos piezas de código para decodificar datos json (local y remoto). Ambos trabajan. También puedo visualizar mis datos locales, pero no los datos remotos. Son exactamente iguales (solo la ubicación del archivo json y el imageUrl difieren). En mi código TestView.swift, que se usa para ambos casos, he dado dos comentarios que apuntan a mi problema.

Mi problema: ¿Cómo necesito definir los Datos de prueba: [Prueba] para el caso remoto, que está bien definido para el caso local?

¿Lo que falta? Por favor ayuda. Soy nuevo en Xcode y SwiftUI, por lo que cualquier ayuda será muy apreciada.

PD Básicamente, estoy intentando basarme en dos tutoriales de Swift (en YouTube), es decir, crear una interfaz de usuario compleja con SwiftUI de principio a fin, SwiftUI obteniendo JSON y datos de imagen con BindableObject.

// Data.swift

import SwiftUI
import Combine

// 1.) Esta primera pieza de código decodifica los datos json locales y los visualiza correctamente

let testData:[Test] = load("test.json")

func load<T:Decodable>(_ filename:String, as type:T.Type = T.self) -> 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)")
    }
}

struct Test_Previews: PreviewProvider {
    static var previews: some View {
        TestView()
    }
}

// 2.) Esta segunda pieza de código decodifica datos json remotos pero no los visualiza

class testDatas: ObservableObject {

    @Published var tests:[Test] = [Test]()

    func getAllTests() {
        let file = URLRequest(url: URL(string: "https://myurl/test.json")!)
        let task = URLSession.shared.dataTask(with: file) { (data, _, error) in
        guard error == nil else { return }

            do {
                let tests = try JSONDecoder().decode([Test].self, from: data!)

                DispatchQueue.main.async {
                        self.tests = tests
                    print(tests)

                }
            } catch {
                print("Failed To decode: ", error)
            }
        }
        task.resume()
    }
        init() {
            getAllTests()
    }
        init(tests: [Test]) {
            self.tests = tests
    }
}

struct Test_Previews: PreviewProvider {
    static var previews: some View {
        TestView()
    }
}

// TestView.swift (utilizado para ambos casos de decodificación)

import SwiftUI

// testData needed here only for the remote case, but this might be wrong and the problem?
let testData:[Test] = [Test]()

struct TestView: View {

    // testDatas needed here only for the remote case to decode json data)
    @ObservedObject var fixer: testDatas = testDatas()

    @EnvironmentObject var loader: ImageLoader

    var categories:[String:[Test]] {
        .init(
            grouping: testData,
            by: {$0.category.rawValue}
        )
    }

    var body: some View {
        NavigationView{
            List (categories.keys.sorted(), id: \String.self) {key in TestRow(categoryName: "\(key).environmentObject(ImageLoader(with: key.imageUrl)) Tests".uppercased(), tests: self.categories[key]!)
                .frame(height: 320)
                .padding(.top)
                .padding(.bottom)
            }
            .navigationBarTitle(Text("TEST"))
        }
    }

}

class ImageLoader:ObservableObject
{
    @Published var data:Data = Data()
    func getImage(imageURL:String) {
        guard let test = URL(string: imageURL) else { return }

        URLSession.shared.dataTask(with: test) { (data, response, error) in
            DispatchQueue.main.async {
                if let data = data {
                    self.data = data
                }
            }
            print(data as Any)
        }.resume()
    }
    init(imageURL:String) {
        getImage(imageURL: imageURL)
    }
}

struct TestView_Previews: PreviewProvider {
    @ObservedObject var imageLoader: ImageLoader
    init(test:String)
    {
        imageLoader = ImageLoader(imageURL: test)
    }
    static var previews: some View {
        TestView()
    }
}
0
user12265655 24 oct. 2019 a las 01:20

1 respuesta

La mejor respuesta

Con la ayuda de @Josh Homann en una pregunta relacionada, pude resolver mi problema. Todo lo que tuve que hacer fue reemplazar "grouping: testData" con "grouping: networkManager.tests" y usando "@ObservedObject var networkManager: NetworkManager = NetworkManager ()". Esto hace que la definición de testData sea redundante.

0
user12265655 7 nov. 2019 a las 16:16