swift Quiz应用程序API由于Nil通过我的JSON解码器而崩溃,但不确定为什么它是nil而不是我的数据

vd2z7a6w  于 2023-03-28  发布在  Swift
关注(0)|答案(1)|浏览(108)

下面是我的代码,我得到了隐式Unwrapped Nil错误,我知道这是因为self.QQs = QQs!行由于!。我不确定为什么QQs是nil,因为我从URL中提取的不是(正如你在链接中看到的那样,它显示了我正在使用的公共JSON)。为什么QQs是nil?

struct QQ: Codable, Identifiable {
    enum CodingKeys: CodingKey {
        case question
        case answer1
        case answer2
        case answer3
        case answer4
        case logo
    }
    
    var id = UUID()
    var question: String
    var answer1: String
    var answer2: String
    var answer3: String
    var answer4: String
    var logo: String
}

class ReadData: ObservableObject  {
    @Published var QQs = [QQ]()
    
    init(){
        loadData()
    }
    
    func loadData()  {
        let url = URL(string: "https://api.jsonbin.io/v3/b/641f82dcace6f33a22fbec99")
        let data = try? Data(contentsOf: url!)
        let QQs2 = try? JSONDecoder().decode([QQ].self, from: data!)
        self.QQs = QQs!
    }
    
}
s4n0splo

s4n0splo1#

您不会从服务器收到数组,也不会从服务器收到类似QQ的任何东西,这就是为什么您的应用程序会因解码而崩溃。
https://api.jsonbin.io/v3/b/641f82dcace6f33a22fbec99放入浏览器,然后将原始json数据复制并粘贴到https://app.quicktype.io/中,正确的模型将为您生成。
调整生成的代码,您就得到了这些模型,如示例代码所示。

struct ContentView: View {
    @StateObject var model = DataManager()
    
    var body: some View {
        VStack {
            if let qData = model.response?.record.questiondata.data {
                List(Array(qData.keys), id: \.self) { key in
                    VStack {
                        Text(qData[key]?.answer1.text ?? "no data")
                        Text(qData[key]?.answer2.text ?? "no data")
                        Text(qData[key]?.answer3.text ?? "no data")
                        Text(qData[key]?.answer4.text ?? "no data")
                    }
                }
            }
        }
        .task {
            await model.loadData()
        }
    }
}

@MainActor
class DataManager: ObservableObject  {
    @Published var response: APIResponse? = nil
    
    func loadData() async  {
        if let url = URL(string: "https://api.jsonbin.io/v3/b/641f82dcace6f33a22fbec99") {
            do {
                let (data, _) = try await URLSession.shared.data(from: url)
                response = try JSONDecoder().decode(APIResponse.self, from: data)
            } catch {
                print(error)
            }
        }
    }
    
}

struct APIResponse: Codable {
    let record: Record
    let metadata: Metadata
}

struct Metadata: Codable {
    let id: String
    let metadataPrivate: Bool
    let createdAt: String

    enum CodingKeys: String, CodingKey {
        case id
        case metadataPrivate = "private"
        case createdAt
    }
}

struct Record: Codable {
    let questiondata: QuestionData
}

struct QuestionData: Codable {
    var data: [String : Quest]
    
    struct AnyKey: CodingKey {
        var stringValue: String
        var intValue: Int?
        
        init?(stringValue: String) {  self.stringValue = stringValue  }
        init?(intValue: Int) { return nil }
    }
    
    init(from decoder: Decoder) throws {
        self.data = [:]
        let container = try decoder.container(keyedBy: AnyKey.self)
        container.allKeys.forEach { key in
            if let theQuest = try? container.decode(Quest.self, forKey: key) {
                self.data[key.stringValue] = theQuest
            }
        }
    }
    
}

struct Quest: Codable {
    let question: String
    let answer1, answer2, answer3, answer4: Answer
}

struct Answer: Codable {
    let logo, text: String

    enum CodingKeys: String, CodingKey {
        case logo
        case text = "Text"
    }
}

相关问题