使用Codable解析嵌套的JSON数据 [英] Using Codable to parse nested JSON data

查看:535
本文介绍了使用Codable解析嵌套的JSON数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Codable解析JSON数据.但是当归结为带有数组的对象时会遇到一些问题.我一直在尝试遵循以下答案,但出现错误Type 'Feature' does not conform to protocol 'Encodable'

I'm trying to use Codable to parse JSON data. But having some problems when it comes down to an object with arrays. I've been trying to follow following answer, but i'm getting an error Type 'Feature' does not conform to protocol 'Encodable'

我想要的JSON数据是纬度和经度数据,但是我正努力学习Codable.我还可以补充一点,我尝试抓住id并运行良好,但是当我尝试更深入时,它只是给我一个错误.

The JSON data I want are the latitude and longitude data, but i'm struggling to hard to learn Codable. I can also add that I tried to grab the id and it worked fine, but when i'm trying to go deeper, it just gives me an error.

有什么建议吗?我确实要使用Codable而不是JSONSerialization.

Any advice? I do want to use Codable and not JSONSerialization.

struct Features: Codable {
    var features: [Feature]
}

struct Feature: Codable {
    var lat: Double
    var long: Double


    enum CodingKeys: String, CodingKey {
        case geometry
    }


    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        let geometry = try values.nestedContainer(keyedBy: CodingKeys.self, forKey: .geometry)
        var coordinates = try geometry.nestedUnkeyedContainer(forKey: .geometry)
        long = try coordinates.decode(Double.self)
        lat = try coordinates.decode(Double.self)

    }
}

JSON响应

{  
   "type":"FeatureCollection",
   "totalFeatures":1761,
   "features":[  
      {  
         "type":"Feature",
         "id":"LTFR_P_RORELSEHINDRADE.3179814",
         "geometry":{  
            "type":"LineString",
            "coordinates":[  
               [  
                  17.929374,
                  59.387507
               ],
               [  
                  17.929364,
                  59.387493
               ]
            ]
         },
         "geometry_name":"GEOMETRY",
         "properties":{  
            "FID":3179814,
            "FEATURE_OBJECT_ID":2406812,
            "FEATURE_VERSION_ID":1,
            "EXTENT_NO":2,
            "VALID_FROM":"2008-10-09T22:00:00Z",
            "CITATION":"0180 2008-09122",
            "STREET_NAME":"Visbyringen",
            "CITY_DISTRICT":"Rinkeby",
            "PARKING_DISTRICT":"<Område saknas>",
            "ADDRESS":"Visbyringen 4",
            "VF_METER":12,
            "VF_PLATS_TYP":"Reserverad p-plats rörelsehindrad",
            "RDT_URL":"https://rdt.transportstyrelsen.se/rdt/AF06_View.aspx?BeslutsMyndighetKod=0180&BeslutadAr=2008&LopNr=09122"
         }
      }
   ]
}

感兴趣的数据

"coordinates":[  
   [  
      17.929374,
      59.387507
   ],
   [  
      17.929364,
      59.387493
   ]
]

推荐答案

编译器给您的错误是因为您的对象不符合Encodable

The error the compiler is giving you is because your object doesn't conform to Encodable

如果您只需要使用JSON->对象,而不必使用其他方法,则可以使用Decodable代替Codable.

If you just need to go JSON -> object and not the other way around then you can use Decodable instead of Codable.

Codable需要符合Encodable,因此您还必须实现encode(to encoder: Encoder)

Codable requires conformance to Encodable so you would also have to implement encode(to encoder: Encoder)

修复该问题之后,还需要修复对嵌套容器的解析.

After you fix that then you also need to fix your parsing of the nested containers.

内部几何对象与外部对象的键不同,因此需要单独的CodingKey来传递.您还需要比当前的位置更深一层.

Your inner geometry object has different keys than your outer object so you need a separate CodingKey to pass. You also need to go one level deeper than you currently are to get to your coordinates.

此版本适用于您所质疑的json:

This version should work for the json in your question:

struct Features: Decodable {
    var features: [Feature]
}

struct Feature: Decodable {
    var lat: Double
    var long: Double

    enum CodingKeys: String, CodingKey {
        case geometry
    }

    enum GeometryKeys: String, CodingKey {
        case coordinates
    }

    init(from decoder: Decoder) throws {
        let values = try decoder.container(keyedBy: CodingKeys.self)
        let geometry = try values.nestedContainer(keyedBy: GeometryKeys.self, forKey: .geometry)
        var coordinates = try geometry.nestedUnkeyedContainer(forKey: .coordinates)

        var longLat = try coordinates.nestedUnkeyedContainer()
        long = try longLat.decode(Double.self)
        lat = try longLat.decode(Double.self)
    }
}

这篇关于使用Codable解析嵌套的JSON数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆