为什么我的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)}