【发布时间】:2023-04-10 14:27:02
【问题描述】:
我正在开发一个 SwiftUI 应用程序,该应用程序应该从 JSON 文件加载问题并将它们一一展示给用户。我关注了a tutorial 如何将JSON-data 加载到视图中,但它不起作用。 JSONDecoder 似乎失败了,有人知道为什么吗?
这是我的代码:
CodableBundleExtension.swift
import Foundation
extension Bundle {
func decode(_ file: String) -> [Question] {
// Locate the JSON-file.
guard let url = self.url(forResource: file, withExtension: nil) else {
fatalError("Failed to locate \(file) in bundle.")
}
// Create a property for the data
guard let data = try? Data(contentsOf: url) else {
fatalError("Failed to load \(file) from bundle.")
}
// Create a decoder
let decoder = JSONDecoder()
// Create a property for the decoded data
guard let loaded = try? decoder.decode([Question].self, from: data) else {
fatalError("Failed to decode \(file) from bundle.")
}
// Return the decoded data
return loaded
}
}
Questions.swift
import SwiftUI
struct Question: Codable, Identifiable {
let id: Int
let question: String
let gamemode: Int
let min_players: Int
let max_platers: Int
let question_type: Int
let language: String
}
ContentView.swift
import SwiftUI
struct ContentView: View {
var body: some View {
let questions : [Question] = Bundle.main.decode("questions.json")
ForEach(questions) { item in
Text(item.question)
}
ZStack {
LinearGradient(
gradient: Gradient(
colors: [.blue, .white]),
startPoint: .topLeading,
endPoint: .bottomTrailing)
.edgesIgnoringSafeArea(.all)
VStack {
Text("The Questions App")
.font(.system(size: 36))
.fontWeight(.bold)
.foregroundColor(.white)
.padding(.top, 40)
.padding(.bottom, 40)
VStack {
Image(systemName: "homepod")
.renderingMode(.original)
.resizable()
.frame(width: /*@START_MENU_TOKEN@*/100/*@END_MENU_TOKEN@*/, height: 140, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/)
.aspectRatio(contentMode: .fit)
Spacer()
Button {
print("tapped")
} label: {
Text("Click Me")
.font(.system(size: 32))
.fontWeight(.medium)
.foregroundColor(.blue)
.frame(width: 200, height: 70, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/)
.background(Color.white)
.cornerRadius(20)
}
Spacer()
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
questions.json
[
{
"id": 1,
"question": "Testquestion 1",
"gamemode": 1,
"min_players": 2,
"max_players": 4,
"question_type": 1,
"language": "NL"
},
{
"id": 2,
"question": "Testquestion 2",
"gamemode": 1,
"min_players": 2,
"max_players": 99,
"question_type": 2,
"language": "NL"
}
]
这是错误:
Fatal error: Failed to decode questions.json from bundle.: file Drinking_App_V1/CodableBundleExtension.swift, line 27
2021-04-25 20:19:29.617268+0200 Questions App V1[13218:851770] Fatal error: Failed to decode questions.json from bundle.: file Questions_App_V1/CodableBundleExtension.swift, line 27
(lldb)
【问题讨论】:
-
而不是
try?使用do-catch并打印错误 -
@Andrew 我如何用这段代码做到这一点?我对 Swift 很陌生..
-
do { let loaded = try decoder.decode(...) } catch { print(error) }见docs.swift.org/swift-book/LanguageGuide/ErrorHandling.html -
第 32 行(已加载返回)现在给出错误:“无法将 'Bool' 类型的返回表达式转换为返回类型 '[Question]'”。我的代码是: do { let loaded = try decoder.decode([Question].self, from: data) } catch { print(error) }
标签: json swiftui jsondecoder