如何解析这个复杂的嵌套Json
Json是有效的,但返回的Json的代码和结构为零 遇到的问题:如何解析这个复杂的嵌套Json,json,swift,swift4.2,jsondecoder,Json,Swift,Swift4.2,Jsondecoder,Json是有效的,但返回的Json的代码和结构为零 遇到的问题: 在JSonDecoder.decode():它返回了这个错误消息: keyNotFound(编码键(stringValue:“项”,intValue:nil),Swift.DecodingError.Context(编码路径:[[U JSONKey(stringValue:“项”,intValue:nil),[U JSONKey(stringValue:“索引0”,intValue:0)],调试说明:“没有与键编码键相关的值(st
keyNotFound(编码键(stringValue:“项”,intValue:nil),Swift.DecodingError.Context(编码路径:[[U JSONKey(stringValue:“项”,intValue:nil),[U JSONKey(stringValue:“索引0”,intValue:0)],调试说明:“没有与键编码键相关的值(stringValue:“项”,intValue:nil)(“项”)”,底层错误:nil))
func getJsonMapData(){
guard let mapUrl = URL(string: "https://xxxxxx/traffic-images") else { return }
URLSession.shared.dataTask(with: mapUrl) { (data, response, error) in
guard error == nil else { return}
guard let data = data else { return}
//- problem:
do {
let LocationArrDict = try JSONDecoder().decode([String:[Location]].self, from: data)else{
print(LocationArrDict)
} catch {
print(error)
}
}.resume()
}
//------------- return Json String:
{
"items":[
{
"timestamp":"2020-12-05T08:45:43+08:00",
"cameras":[
{
"timestamp":"2020-11-05T08:42:43+08:00",
"image":"https://xxxxxxxxx/traffic-images/2020/12/2ab06cd8-4dcf-434c-b758-804e690e57db.jpg",
"location":{
"latitude":1.29531332,
"longitude":103.871146
},
"camera_id":"1001",
"image_metadata":{
"height":240,
"width":320,
"md5":"c9686a013f3a2ed4af61260811661fc4"
}
},
{
"timestamp":"2020-11-05T08:42:43+08:00",
"image":"https://xxxxxxxxxx/traffic-images/2020/12/9f6d307e-8b05-414d-b27d-bf1414aa2cc7.jpg",
"location":{
"latitude":1.319541067,
"longitude":103.8785627
},
"camera_id":"1002",
"image_metadata":{
"height":240,
"width":320,
"md5":"78060d8fbdd241adf43a2f1ae5d252b1"
}
},
........
{
"timestamp":"2020-12-05T08:42:43+08:00",
"image":"https://xxxxxx/traffic-images/2020/12/98f64fe6-5985-4a8a-852f-0be24b0a6271.jpg",
"location":{
"latitude":1.41270056,
"longitude":103.80642712
},
"camera_id":"9706",
"image_metadata":{
"height":360,
"width":640,
"md5":"f63d54176620fa1d9896fa438b3cc753"
}
}
]
}
],
"api_info":{
"status":"healthy"
}
}
//------------ struct for the return Json result:
// MARK: - Location
struct Location: Codable {
let items: [Item]
let apiInfo: APIInfo
enum CodingKeys: String, CodingKey {
case items
case apiInfo = "api_info"
}
}
// MARK: - APIInfo
struct APIInfo: Codable {
let status: String
}
// MARK: - Item
struct Item: Codable {
let timestamp: Date
let cameras: [Camera]
}
// MARK: - Camera
struct Camera: Codable {
let timestamp: Date
let image: String
let location: LocationClass
let cameraID: String
let imageMetadata: ImageMetadata
enum CodingKeys: String, CodingKey {
case timestamp, image, location
case cameraID = "camera_id"
case imageMetadata = "image_metadata"
}
}
// MARK: - ImageMetadata
struct ImageMetadata: Codable {
let height, width: Int
let md5: String
}
// MARK: - LocationClass
struct LocationClass: Codable {
let latitude, longitude: Double
}
``
错误#1:要解码的类型错误它必须是位置.self
错误2:要将ISO日期解码为
date
,必须添加.iso8601
日期解码策略
do {
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601
let locationArrDict = try decoder.decode(Location.self, from: data)
print(locationArrDict)
} catch {
print(error)
}
您可以将表示URL的字符串直接解码到
URL
您必须创建数据模型,并将它们描述为您期望收到的响应。我将根据您的json为您提供一个简单的示例,您将如何对其进行解码
首先,为了使用JSONDecoder
解码JSON,您的模型必须符合Decodable
协议。然后你必须创建那些模型
struct项:可解码{
让时间戳:日期
//让摄像机:[……]
}
结构apinfo:可解码{
枚举状态:字符串,可解码{
病例健康
}
让状态:状态
}
结构响应:可解码{
出租项目:[项目]
让我们看看apinfo:apinfo
}
然后您必须配置JSONDecoder
并解码该JSON。我们可以清楚地看到,您的JSON使用了snake\u case
命名约定,而这不是jsondeconder
的默认约定,因此您必须设置它。同样的情况也适用于日期-它用于iso8601
表示标准
让jsonDecoder=jsonDecoder()
jsonDecoder.dateDecodingStrategy=.iso8601
jsonDecoder.keyDecodingStrategy=.convertFromSnakeCase
最后,你有你解码它
do{
让response=尝试jsonDecoder.decode(response.self,from:jsonData)
打印(答复)
}抓住{
打印(错误)
}
不要尝试?
,永远不要尝试?
在Codable
环境中忽略错误。捕捉错误并打印它。至少有两个。您发布的JSON似乎无效。括号不平衡。@Sweeper,json结果太长,无法在此处显示。我检查了在线json验证程序。我尝试[Location].self[String:[Location]].self或Location.self,它们不起作用。无论实际的JSON是否太长,都应该显示一个。显示重现问题的最短、有效的JSON。@请参阅更新。json结果如上图所示。代码部分指出了这个问题。让我研究一下您的解决方案,然后很快回到这里。似乎我在使用您发布的代码->类型不匹配(swift.double,swift.decoding error.Context)后出错了……“预期解码double,但改为查找/dat”你真的将解码器实例用于日期解码策略吗?错误表明你没有。你的解决方案有效。我不想一下子问这么多问题。我认为我的json解析需要很多帮助才能学习。我认为这个练习将提高我对json的理解。我有两个关于json的问题。谢谢你的帮助:对不起,我我不熟悉谷歌地图API