简体   繁体   English

JSONDecoder 解析数据但返回 nil

[英]JSONDecoder Parsing Data but returning nil

I am making a simple get request that is returning nil.我正在做一个返回 nil 的简单 get 请求。 I have made other get requests to the same API with success, so I don't know if my struct is wrong.我已经成功地向同一个 API 发出了其他 get 请求,所以我不知道我的结构是否有误。

API Response: API 回复:

{
    "response": {
        "cursor": 0,
        "results": [{
            "MessageBody": "test",
            "Subject": "parent Update",
            "Created Date": "2022-03-25T19:41:53.590Z",
            "Created By": "admin_user_schoolnotifier_test",
            "Modified Date": "2022-03-25T19:41:53.590Z",
            "_id": "1648237313585x594391342134115600"
        }, {
            "MessageBody": "test forever",
            "Subject": "parent Update",
            "Created Date": "2022-03-25T19:44:31.121Z",
            "Created By": "admin_user_schoolnotifier_test",
            "Modified Date": "2022-03-25T19:44:31.121Z",
            "_id": "1648237471114x629833405395263200"
        }, {
            "MessageBody": "hi there",
            "Subject": "parent Update",
            "Created Date": "2022-03-25T20:43:59.113Z",
            "Created By": "admin_user_schoolnotifier_test",
            "Modified Date": "2022-03-25T20:43:59.113Z",
            "_id": "1648241039108x652255616347552800"
        }],
        "remaining": 0,
        "count": 3
    }
}

Struct:结构:

import Foundation

// MARK: - GetMessage
struct GetMessage: Codable {
    let response: Response
}

// MARK: - Response
struct Response: Codable {
    let cursor: Int
    let results: [Result]
    let remaining, count: Int
}

// MARK: - Result
struct Result: Codable {
    let MessageBody, subject, createdDate, createdBy: String
    let modifiedDate, id: String

    enum CodingKeys: String, CodingKey {
        case MessageBody
        case subject
        case createdDate
        case createdBy
        case modifiedDate
        case id
    }
}

Network Call:网络电话:

class Network{
    func getMessages(success: @escaping (GetMessage)->()){
        let url = URL(string: "https://schoolnotifier.bubbleapps.io/version-test/api/1.1/obj/message")!
        let task = URLSession.shared.dataTask(with: url) { data, response, error in
            if let data = data {
                do {
                    let decoder = JSONDecoder()
                    let messages = try decoder.decode(GetMessage.self, from: data)
                    print(messages as Any)
                } catch DecodingError.dataCorrupted(let context) {
                    print(context)
                } catch DecodingError.keyNotFound(let key, let context) {
                    print("Key '\(key)' not found:", context.debugDescription)
                    print("codingPath:", context.codingPath)
                } catch DecodingError.valueNotFound(let value, let context) {
                    print("Value '\(value)' not found:", context.debugDescription)
                    print("codingPath:", context.codingPath)
                } catch DecodingError.typeMismatch(let type, let context) {
                    print("Type '\(type)' mismatch:", context.debugDescription)
                    print("codingPath:", context.codingPath)
                } catch {
                    print("error: ", error)
                }
            }
        }
        task.resume()
    }
}

Output: Output:

Key 'CodingKeys(stringValue: "subject", intValue: nil)' not found: No value associated with key CodingKeys(stringValue: "subject", intValue: nil) ("subject").未找到键 'CodingKeys(stringValue: "subject", intValue: nil)':没有与键 CodingKeys(stringValue: "subject", intValue: nil) ("subject") 关联的值。 codingPath: [CodingKeys(stringValue: "response", intValue: nil), CodingKeys(stringValue: "results", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0)] codingPath: [CodingKeys(stringValue: "response", intValue: nil), CodingKeys(stringValue: "results", intValue: nil), _JSONKey(stringValue: "Index 0", intValue: 0)]

Many of your keys don't match.您的许多键不匹配。 It is case sensitive.它区分大小写。 Also _id is prefixed by an underscore. _id也以下划线为前缀。

struct Result: Codable {
    let messageBody, subject, createdDate, createdBy: String
    let modifiedDate, id: String

    enum CodingKeys: String, CodingKey {
        case messageBody = "MessageBody"
        case subject = "Subject"
        case createdDate = "Created Date"
        case createdBy = "Created By"
        case modifiedDate = "Modified Date"
        case id = "_id"
    }
}

Frankly, if you are in control of the backend, I would advise changing the key names in the response to be either camelCase or snake_case, both of which are common conventions.坦率地说,如果您控制后端,我会建议将响应中的键名称更改为驼峰式或蛇形式,这两种都是常见的约定。 But I would not advise having spaces in your key names and the leading underscore of the id is fairly unusual.但我不建议在您的键名中使用空格,并且id的前导下划线是相当不寻常的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM