包含qoutes的Swift 4 Codable解码阵列

时间:2017-12-27 08:28:06

标签: json swift swift4 codable decodable

来自API的格式错误的json响应:

"[]"

我需要解码这个"形状"我的自定义结构的关键,这看起来不是什么大不了但我有引用数组的引号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)

和corse这个调用有效(仅用于测试目的):

"[[12.557642081093963,99.95730806607756], [12.558081912207575,99.96078957337888], [12.558469381851197,99.96072520036252], [12.558029551400157,99.9572275998071]]"

并输出此信息:

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 } } } 将这个String样式包装的json数组解码为Swift数组?

我设法做了一些解决方法,但它确实有效,但它看起来并不是一个好的解决方案。将在此处发布,但问题是&#34;有没有办法通过Codable&#34;正常实现这一点。仍然开放

class PhonePresenter(
    private val preference: DataPreference,
    private val ioScheduler: Scheduler) {        
    @Inject consturctor(preference: DataPreference):this(perference, Schedulers.io())
}

1 个答案:

答案 0 :(得分:0)

可能会让您了解如何处理此类String

let rawString: String = "[[12.557642081093963,99.95730806607756], [12.558081912207575,99.96078957337888], [12.558469381851197,99.96072520036252], [12.558029551400157,99.9572275998071]]"

这里发生的事情基本上是将String转换回Data并尝试将此 data解析为JSON,方法是将其解码为{ {1}}:

[[Double]]

注意: 只要if let data: Data = rawString.data(using: .utf8) { let coordinates: [[Double]]? = try? JSONDecoder().decode([[Double]].self, from: data) // yes, it is an array now as I wanted! } 应该是引号内的有效JSON,它就不会失败。当然,为什么响应只是间接地包含JSON是非常可疑的,但你可以轻松地弥合这种情况,如果你 - 正如我上面所说的那样 - 期望在那里有一个有效的JSON。