使用Swift中的可解码代码解析嵌套JSON
我正在尝试解析这个JSON响应使用Swift中的可解码代码解析嵌套JSON,json,swift,decodable,Json,Swift,Decodable,我正在尝试解析这个JSON响应 { "payload": { "bgl_category": [{ "number": "X", "name": "", "parent_number": null, "id":
{
"payload": {
"bgl_category": [{
"number": "X",
"name": "",
"parent_number": null,
"id": 48488,
"description": "Baustellenunterk\u00fcnfte, Container",
"children_count": 6
}, {
"number": "Y",
"name": "",
"parent_number": null,
"id": 49586,
"description": "Ger\u00e4te f\u00fcr Vermessung, Labor, B\u00fcro, Kommunikation, \u00dcberwachung, K\u00fcche",
"children_count": 7
}]
},
"meta": {
"total": 21
}
}
我感兴趣的是在TableViewCell中查看编号
和说明
以下是我试图做的:
//MARK: - BGLCats
struct BGLCats: Decodable {
let meta : Meta!
let payload : Payload!
}
//MARK: - Payload
struct Payload: Decodable {
let bglCategory : [BglCategory]!
}
//MARK: - BglCategory
struct BglCategory: Decodable {
let descriptionField : String
let id : Int
let name : String
let number : String
let parentNumber : Int
}
//MARK: - Meta
struct Meta: Decodable {
let total : Int
}
API请求:
fileprivate func getBgls() {
guard let authToken = getAuthToken() else {
return
}
let headers = [
"content-type" : "application/json",
"cache-control": "no-cache",
"Accept" : "application/json",
"Authorization": "\(authToken)"
]
let request = NSMutableURLRequest(url: NSURL(string: "https://api-dev.com")! as URL, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.allHTTPHeaderFields = headers
let endpoint = "https://api-dev.com"
guard let url = URL(string: endpoint) else { return }
URLSession.shared.dataTask(with: request as URLRequest) {(data, response, error) in
guard let data = data else { return }
do {
let BGLList = try JSONDecoder().decode(BglCategory.self, from: data)
print(BGLList)
DispatchQueue.main.sync { [ weak self] in
self?.number = BGLList.number
self?.desc = BGLList.descriptionField
// self?.id = BGLList.id
print("Number: \(self?.number ?? "Unknown" )")
print("desc: \(self?.desc ?? "Unknown" )")
// print("id: \(self?.id ?? 0 )")
}
} catch let jsonError {
print("Error Serializing JSON:", jsonError)
}
}.resume()
}
但我得到了一个错误:
Error Serializing JSON: keyNotFound(CodingKeys(stringValue: "childrenCount", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"childrenCount\", intValue: nil) (\"childrenCount\").", underlyingError: nil))
问题是JSONDecoder不知道例如
bglCategory
在JSON负载中表示为bgl\u category
。如果JSON名称与变量名称不同,则需要将CodingKeys
实现到Decodable
就你而言:
struct BglCategory:可解码{
let descriptionField:字符串
让id:Int
let name:String
编号:String
让家长编号:Int?
枚举编码键:字符串,编码键{
案例id、名称、编号
案例描述字段=“描述”
case parentNumber=“parent\u number”
}
}
结构有效载荷:可解码{
让bglCategory:[bglCategory]!
枚举编码键:字符串,编码键{
案例bglCategory=“bgl\u类别”
}
}
这里有几个问题
您(基本上)正确地创建了模型,但只有两个不匹配:
struct BglCategory: Decodable {
let description : String // renamed, to match "description" in JSON
let parentNum: Int? // optional, because some values are null
// ...
}
第二个问题是,您的模型属性是camelCased,而JSON是snake\u cased。JSONDecoder有一个.convertFromSnakeCase
开始功能来自动处理这个问题。在解码之前,您需要在解码器上设置它
第三个问题是您需要解码根对象BGLCats
,而不是BglCategory
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase // set the decoding strategy
let bglCats = try decoder.decode(BGLCats.self, from: data) // decode BGLCats
let blgCategories = bglCats.payload.bglCategory
错误消息与JSON和代码不匹配。您应该会遇到其他错误。在使用camelCased名称时,必须至少指定
convertFromSnakeCase
策略,根对象是BGLCats
。请注意:如果有本机对应的类,请不要使用NS…
类。