ios - 使用 Codable 解析嵌套的 JSON 数据

标签 ios json swift codable

我正在尝试使用 Codable 来解析 JSON 数据。但是当涉及到带有数组的对象时会遇到一些问题。我一直在尝试关注 answer ,但我收到错误 Type 'Feature' does not conform to protocol 'Encodable'

我想要的JSON数据是经纬度数据,但是我正在努力学习Codable。我还可以补充一点,我试图获取 id 并且它工作正常,但是当我试图更深入时,它只会给我一个错误。

有什么建议吗?我确实想使用 Codable 而不是 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

如果您只需要转到 JSON -> 对象而不是相反,那么您可以使用 Decodable 而不是 Codable

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

在你修复它之后,你还需要修复你对嵌套容器的解析。

您的内部几何对象与外部对象具有不同的键,因此您需要一个单独的 CodingKey 来传递。您还需要比目前更深一层才能获得您的坐标。

此版本应该适用于您问题中的 json:

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)
    }
}

关于ios - 使用 Codable 解析嵌套的 JSON 数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50065460/

相关文章:

objective-c - 如何使 MPMoviePlayerController 在横向全屏而不是纵向全屏

javascript - 从http请求函数返回数据

ios - 在 iPad 上呈现 View Controller 只允许 .Popover

ios - Swift Playgrounds 中的观看次数有限

ios - 核心数据迁移 : 'Can' t merge models with two different entities. ..'

objective-c - 在Cocos2D、iOS中绘制填充的动态多边形

ios - 使用 RestKit 0.20 进行 POST - NSManagedObjectContext 问题

c# - 使用JSON.NET序列化复杂字典时更改 'Key'和 'Value'的名称

javascript - 来自 Rails Controller 的 JSON 自定义格式

ios - 基于类的 Swift 常量是否强制为可选