swift - 尽管使用 SwiftUI 成功解码了 json 数据,但没有图像
问题描述
我有两段代码来解码 json 数据(本地和远程)。两者都有效。我还能够可视化我的本地数据,但不能可视化远程数据。它们完全相同(只是 json 文件和 imageUrl 的位置不同)。在用于这两种情况的 TestView.swift 代码中,我给出了两条指出我的问题的注释。
我的问题:我如何需要为远程案例定义 testData:[Test],这对于本地案例来说是很好的定义?
什么不见了?请帮忙。我是 Xcode 和 SwiftUI 的新手,因此我们将不胜感激。
PS 基本上我正在尝试构建两个 Swift 教程(在 YouTube 上),即从头到尾使用 SwiftUI 构建复杂的 UI,使用 BindableObject 获取 JSON 和图像数据的 SwiftUI。
// 数据.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 在相关问题上的帮助下,我可以解决我的问题。我所要做的就是将“grouping: testData”替换为“grouping: networkManager.tests”并使用“@ObservedObject var networkManager: NetworkManager = NetworkManager()”。这使得 testData 的定义变得多余。
推荐阅读
- google-cloud-platform - GCP图片存储策略
- ruby-on-rails - 发布请求中没有路线匹配 [GET]
- html - 如何使这个div中的内容在一行中?
- ios - SwiftUI 模态表在半秒后自行关闭
- facebook - Facebook 广告目标、应用安装量与流量
- javascript - 我应该使用更改处理程序从项目类型数组中填充项目数组吗?
- tensorflow - Keras预测相同输入图像的不同输出
- node.js - Node JS 永久访问存储在数据库中的媒体文件
- java - 使用 JavaOsc 从 Behringer X32 获取仪表读数
- python - 初始化小部件的正确方法是什么?