swift - 尽管使用 SwiftUI 成功解码 json 数据,但没有图像

标签 swift swiftui

我有两段代码来解码 json 数据(本地和远程)。两者都有效。我还可以可视化本地数据,但不能可视化远程数据。它们完全相同(只是 json 文件和 imageUrl 的位置不同)。在我的 TestView.swift 代码(用于这两种情况)中,我给出了两条指出我的问题的注释。

我的问题:如何为远程案例定义 testData:[Test],而本地案例已明确定义该测试数据?

缺少什么?请帮忙。我是 Xcode 和 SwiftUI 的新手,因此我们将不胜感激任何帮助。

附注基本上,我试图在两个 Swift 教程(在 YouTube 上)的基础上进行构建,即从头到尾使用 SwiftUI 构建复杂的 UI、使用 BindableObject 的 SwiftUI 获取 JSON 和图像数据。

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

最佳答案

在@Josh Homann 对相关问题的帮助下,我可以解决我的问题。我所要做的就是将“分组:testData”替换为“分组:networkManager.tests”并使用“@ObservedObject var networkManager:NetworkManager = NetworkManager()”。这使得 testData 的定义变得多余。

关于swift - 尽管使用 SwiftUI 成功解码 json 数据,但没有图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58531681/

相关文章:

swift - 为什么 Error 总是 NSError?

swiftui - 是否可以使用 SwiftUI 在 TextField 上设置字符限制?

ios - 选择后 SwiftUI 选择器动画错误

ios - 关闭模态视图时未调用 onDisappear

swiftui - 为什么 View 在 SwiftUI 中没有完全破坏

ios - 我的应用程序崩溃且没有错误消息 我如何才能找出它的来源?

ios - Metal - 在传递给自定义内核过滤器之前调整视频缓冲区的大小

ios - Swift 中来自两个不同 JSON 的数据放入同一结构中

Mac 上的 SwiftUI : Close Window and open another one

带有可选闭包的 Swift 选择器函数?