Нет изображений, несмотря на успешное декодирование данных JSON с SwiftUI - PullRequest
0 голосов
/ 24 октября 2019

У меня есть два фрагмента кода для декодирования данных JSON (локальный и удаленный). Оба работают. Я также могу визуализировать свои локальные данные, но не удаленные данные. Они абсолютно одинаковы (отличается только расположение файла json и imageUrl). В моем коде TestView.swift, который используется в обоих случаях, я дал два комментария, которые указывают на мою проблему.

Моя проблема: Как мне определить testData: [Test] для удаленного случая,что хорошо определено для локального случая?

Чего не хватает? Пожалуйста помоги. Я новичок в Xcode и SwiftUI, поэтому любая помощь будет принята с благодарностью.

PS В основном я пытаюсь использовать два Swift Tutorials (на YouTube), то есть создать сложный интерфейс с SwiftUI от Start до Finish, SwiftUIИзвлечение данных JSON и изображений с помощью BindableObject.

// Data.swift

import SwiftUI
import Combine

// 1.) Этот первый фрагмент кода декодирует локальные данные json и правильно визуализирует их

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.) Этот второй фрагмент кода декодирует удаленные данные JSON, но не отображает их

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 (используется в обоих случаях декодирования)

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()
    }
}

1 Ответ

0 голосов
/ 07 ноября 2019

С некоторой помощью @Josh Homann по связанному вопросу я мог решить мою проблему. Все, что мне нужно было сделать - это заменить «grouping: testData» на «grouping: networkManager.tests» и использовать «@ObservedObject var networkManager: NetworkManager = NetworkManager ()». Это делает определение testData избыточным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...