为什么我的SwiftuiJSondeCoder会给出一个致命错误?
我正在开发一个为什么我的SwiftuiJSondeCoder会给出一个致命错误?,json,swiftui,jsondecoder,Json,Swiftui,Jsondecoder,我正在开发一个SwiftUI应用程序,它应该从一个JSON文件中加载问题,并将它们逐个显示给用户。我接着介绍了如何将JSON数据加载到视图中,但它不起作用。JSONDecoder似乎失败了,有人知道为什么吗 这是我的密码: CodableBundleExtension.swift import Foundation extension Bundle { func decode(_ file: String) -> [Question] { // Locate th
SwiftUI
应用程序,它应该从一个JSON文件中加载问题,并将它们逐个显示给用户。我接着介绍了如何将JSON数据
加载到视图中,但它不起作用。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
}
}
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
}
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()
}
}
问题。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
}
}
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
}
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()
}
}
ContentView.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
}
}
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
}
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)
如果使用do/catch:
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.")
}
do {
let data = try Data(contentsOf: url)
let decoder = JSONDecoder()
return try decoder.decode([Question].self, from: data)
} catch {
print(error)
fatalError("Failed to decode \(file) from bundle.")
}
}
}
您将看到以下错误:
keyNotFound(CodingKeys(stringValue: "max_platers", intValue: nil), Swift.DecodingError.Context(codingPath: [_JSONKey(stringValue: "Index 0", intValue: 0)], debugDescription: "No value associated with key CodingKeys(stringValue: \"max_platers\", intValue: nil) (\"max_platers\").", underlyingError: nil))
这告诉您,JSON中对于max\u platers
没有任何价值,正如您所看到的,这是对max\u players
的拼写错误
将模型转换为:
struct Question: Codable, Identifiable {
let id: Int
let question: String
let gamemode: Int
let min_players: Int
let max_players: Int //<-- Here
let question_type: Int
let language: String
}
struct问题:可编码、可识别{
让id:Int
让我们提问:字符串
让游戏模式:Int
让min_玩家:Int
让max_players:Int//而不是执行try?
使用do catch
并打印error@Andrew如何使用这段代码?我对Swift非常陌生。do{let loaded=try decoder.decode(…)}catch{print(error)}
参见第32行(return loaded)现在给出了一个错误:无法将“Bool”类型的返回表达式转换为返回类型“[Question]”。我的代码是:do{let loader=try decoder.decode([Question].self,from:data)}catch{print(error)}