Unexpected error: keyNotFound(CodingKeys(stringValue: "id", intValue: nil),
Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "data", intValue: nil)],
debugDescription: "No value associated with key CodingKeys(stringValue: "id", intValue: nil)
("id").", underlyingError: nil)).
响应数据
{
"msg": {
"success": [
""
]
},
"data": {
"jobs": {
"current_page": 1,
"data": [
{
"id": 154,
"user": "UserName"}
]
}
}
}
服务呼叫
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
if let error = error {
print("error: (error)")
} else {
if let response = response as? HTTPURLResponse {
print("statusCode: (response.statusCode)")
}
if let data = data, let dataString = String(data: data, encoding: .utf8) {
let jsonData = dataString.data(using: .utf8)!
do {
let jsonDecoder = JSONDecoder()
let user = try jsonDecoder.decode(JobListModel.self, from: data)
print("Hello (user.msg )")
} catch {
print("Unexpected error: (error).")
}
}
}
}
ModelClass。
struct JobListModel: Codable {
let msg: Msg
let data: Data
private enum CodingKeys: String, CodingKey {
case msg = "msg"
case data = "data"
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
msg = try values.decode(Msg.self, forKey: .msg)
data = try values.decode(Data.self, forKey: .data)
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(msg, forKey: .msg)
try container.encode(data, forKey: .data)
}
}
出现这种情况是因为您的解码模型不正确。使用以下模型:
struct JobListModel: Codable {
let msg: Msg
let data: JobListData
}
struct JobListData: Codable {
let jobs: Jobs
}
struct Jobs: Codable {
let currentPage: Int
let data: [JobData]
enum CodingKeys: String, CodingKey {
case currentPage = "current_page"
case data
}
}
struct JobData: Codable {
let id: Int
let user: String
}
struct Msg: Codable {
let success: [String]
}
原因:
在您的模型中,您使用Data
作为JSON响应中data
键的类型。
Data
是一个预定义的类型,这就是解析时抛出错误的原因。
解决方案:
您需要将其修改为某种自定义类型,例如JobListData
。因此,您的Codable
型号应该是
struct JobListModel: Codable {
let msg: Msg
let data: JobListData
}
struct JobListData: Codable {
let jobs: Jobs
}
struct Jobs: Codable {
let currentPage: Int
let data: [JobsData]
}
struct JobsData: Codable {
let id: Int
let user: String
}
struct Msg: Codable {
let success: [String]
}
您现在可以像这样解析data
,
do {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let response = try decoder.decode(JobListModel.self, from: data)
print(response)
} catch {
print(error)
}
在上面的代码中,我使用了convertFromSnakeCase
作为decoder's
keyDecodingStrategy
。这样就可以避免只为处理json响应中的snake case键而显式定义enum CodingKeys
。
注意:当没有特定的解析内容时,不要显式编写init(from:)
和encode(to:)
的定义。如果您正确设计了模型,Codable
中的直接解析将由编译器自动处理。