来自 API 的格式非常糟糕的 json 响应:
[{
"id": "1",
"shape": "{
"coordinates": "[[12.557642081093963,99.95730806607756], [12.558081912207575,99.96078957337888], [12.558469381851197,99.96072520036252], [12.558029551400157,99.9572275998071]]"}"
}]
我需要将这个“形状”键解码到我的自定义结构中,这似乎没什么大不了的,但我有引号包裹着数组"[]"
所以,我有什么:
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(Identifier.self, forKey: .id)
shape = try container
.nestedContainer(keyedBy: ShapeCoordinatesCodingKeys.self, forKey: .shape)
.decode([[Double]].self, forKey: .coordinates)
.flatMap {
$0.count > 1 ? Location(latitude: $0[0], longitude: $0[1]) : nil
}
}
合理地有错误
"Expected to decode Array<Any> but found a string/data instead."
而且这个电话有效(仅用于测试目的):
po try container.nestedContainer(keyedBy: ShapeCoordinatesCodingKeys.self, forKey: .shape).decode(String.self, forKey: .coordinates)
并有这个输出:
"[[12.557642081093963,99.95730806607756], [12.558081912207575,99.96078957337888], [12.558469381851197,99.96072520036252], [12.558029551400157,99.9572275998071]]"
所以有什么方法可以将这个字符串样式包装的 json 数组解码为 Swift 数组Codable
?
我设法做了一些解决方法,它有效,但它似乎根本不是一个好的解决方案。将在此处发布,但问题“是否有任何方法可以正常使用 Codable 实现此功能”仍处于打开状态
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(Identifier.self, forKey: .id)
do {
shape = try container
.nestedContainer(keyedBy: ShapeCoordinatesCodingKeys.self, forKey: .shape)
.decode([[Double]].self, forKey: .coordinates)
.flatMap {
$0.count > 1 ? Location(latitude: $0[0], longitude: $0[1]) : nil
}
}
catch {
guard let coordinatesData = try container
.nestedContainer(keyedBy: ShapeCoordinatesCodingKeys.self, forKey: .shape)
.decode(String.self, forKey: .coordinates).data(using: .utf8) else {
throw DecodingError.dataCorrupted(
DecodingError.Context(
codingPath: [ShapeCoordinatesCodingKeys.coordinates],
debugDescription: "Array or String?"
)
)
}
shape = try JSONDecoder()
.decode([[Double]].self, from: coordinatesData)
.flatMap {
$0.count > 1 ? Location(latitude: $0[0], longitude: $0[1]) : nil
}
}
}