Json响应解析为可编码的字符串,以发现错误的KeyNotFound。可编码到包装器类时为KeyNotFound
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
。这样,您可以避免显式定义enum CodingKeys
仅用于处理json响应中的snake-case keys。
注:当没有特定于解析的内容时,请不要明确写出init(from:)
和encode(to:)
的定义。假设您正确设计了模型,Codable
中的直接解析将由编译器自动处理。