解码 JSON 时出错 - keyNotFound(CodingKeys

Posted

技术标签:

【中文标题】解码 JSON 时出错 - keyNotFound(CodingKeys【英文标题】:Error when decoding JSON - keyNotFound(CodingKeys 【发布时间】:2018-11-19 14:58:47 【问题描述】:

我正在尝试通过网络解析 JSON 数据。下面你可以看到魔法发生的地方。

func getBookingsForDate(date: String, completionHandler: @escaping ([String:String]) -> Void )

struct bookings: Codable 

    var bookieName : String
    var bookieNumber: String
    var booked: String
    var bookingTime: String

    private enum Codingkeys: String, CodingKey

        case bookieName
        case bookieNumber
        case booked
        case bookingTime
    


let params = ["date":date]

let urlString = "http://mscissorss.pythonanywhere.com/getBookings/"
Alamofire.request(urlString, method: .get, parameters: params).responseJSON 
    response in
    switch response.result 
    case .success(let JSON):

        let decoder = JSONDecoder()
        guard let _ = response.data else
            return
        
        do 
            let loginDetails = try decoder.decode(bookings.self, from: response.data!)
            print(loginDetails)
         catch let err
            print(err)
        

        //let bookings = JSON as! NSDictionary
        //completionHandler(JSON)
        /*
        do 
            let decoder = JSONDecoder()
            let gitData = try decoder.decode(bookings.self, from: JSON)
            print(gitData.bookieName)

         catch let err 
            print("Err", err)
        
        */
        break
    case .failure(let error):
        print(error)
    


鉴于代码我收到以下错误消息:

keyNotFound(CodingKeys(stringValue: "bookieName", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"bookieName\", intValue: nil) (\"bookieName\").", underlyingError: nil))

我得到的 JSON 响应如下所示:


    0 =     
        booked = false;
        bookieName = "";
        bookieNumber = "";
        bookingTime = "10:00";
    ;
    1 =     
        booked = false;
        bookieName = "";
        bookieNumber = "";
        bookingTime = "10:30";
    ;
    10 =     
        booked = false;
        bookieName = "";
        bookieNumber = "";
        bookingTime = "15:00";
    ;
    11 =     
        booked = false;
        bookieName = "";
        bookieNumber = "";
        bookingTime = "15:30";
    ;
    12 =     
        booked = false;
        bookieName = "";
        bookieNumber = "";
        bookingTime = "16:00";
    ;
    13 =     
        booked = false;
        bookieName = "";
        bookieNumber = "";
        bookingTime = "16:30";
    ;
    14 =     
        booked = false;
        bookieName = "";
        bookieNumber = "";
        bookingTime = "17:00";
    ;
    15 =     
        booked = false;
        bookieName = "";
        bookieNumber = "";
        bookingTime = "17:30";
    ;
    16 =     
        booked = false;
        bookieName = "";
        bookieNumber = "";
        bookingTime = "18:00";
    ;
    2 =     
        booked = false;
        bookieName = "";
        bookieNumber = "";
        bookingTime = "11:00";
    ;

这是我第一次解码,所以如果你有答案,请尝试解释一下为什么我需要做出我需要的改变。

更新

将代码更改为@sh_khan 和@vadian 建议的代码后,它可以解析它,但是我仍然在解析的对象中收到此错误:

["1": MagicS.(unknown context at 0x106932738).bookings(bookieName: "", bookieNumber: "", booked: "false", bookingTime: "10:30"), 
"0": MagicS.(unknown context at 0x106932738).bookings(bookieName: "", bookieNumber: "", booked: "false", bookingTime: "10:00"),

另外,如果我希望能够访问单个值,让我们说带有键 "0" -> bookieName 的第一项,我将如何使用 loginDetails 来做到这一点

【问题讨论】:

您不是用“11”键管理第一级(例如,实际上是所有其他键)。您可以使用当前代码解码的内容类似于:"booked":false,"bookieName":"","bookieNumber":"","bookingTime":"10:00" 【参考方案1】:

首先bookedBool,如果您不重命名密钥,则不需要private enum Codingkeys

struct Booking: Codable 

   let bookieName : String
   let bookieNumber: String
   let booked: Bool
   let bookingTime: String


第二次这样解码

let loginDetails = try decoder.decode([String:Booking].self, from: response.data!)

【讨论】:

解析成功上下文就是你写类的地方 我不明白你的意思。你能用另一种方式解释吗? @sh_Khan 你的上下文是 projectName.className【参考方案2】:

根对象是具有String 键和Bookings 值的字典 - 请以大写字母开头命名结构。

所以你必须解码

let loginDetails = try decoder.decode([String:Bookings].self, from: response.data!)

【讨论】:

unknown contextkeyNotFound(CodingKeys 的问题无关。而 MagicS 是什么?获取特定的值关键就写loginDetails["0"]!.bookieName MagicS 是我的 swift 项目的名称。感谢您回答其他问题 @vadian

以上是关于解码 JSON 时出错 - keyNotFound(CodingKeys的主要内容,如果未能解决你的问题,请参考以下文章

使用 Alamofire 解码 json 时出错

我在 Swift 5 上解码 json 时出错

Swift4:从文件中解码 json 时出错

Swift 可编码解析 keyNotFound

Apollo graphQL:在 iOS swift 中使用自定义标量时解码数组时出错

url解码和发布数据后出错