我正在使用这个库,它创建了非空集合,如数组,字典和字符串。 https://github.com/pointfreeco/swift-nonempty
当我解码到非空数组时,出现以下错误
Swift.DecodingError.typeMismatch(Swift.Dictionary,Swift.DecodingError.Context(codingPath:[CodingKeys(stringValue:“ poiList”,intValue:nil)]],debugDescription:“希望对Dictionary进行解码,但找到了一个数组。” ,underlyingError:nil))
这是我的结构
struct LocationCarModel: Codable {
// MARK: - Properties
var poiList: NonEmptyArray<PointOfInterest>
// MARK: - PointOfInterest
struct PointOfInterest: Codable {
var id: Int
var coordinate: Position
var fleetType: String
let numberPlate = "HCD837EC"
let model: String = "Tesla S"
let fuel: Double = 0.9
}
}
这是我得到的回复https://fake-poi-api.mytaxi.com/?p2Lat=53.394655&p1Lon=9.757589&p1Lat=53.694865&p2Lon=10.099891
这就是我解码它的方式。
public extension Decodable {
static func parse(from item: Any?, strategy: JSONDecoder.KeyDecodingStrategy = .useDefaultKeys) -> Self? {
guard let data = self.data(from: item) else {
return nil
}
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = strategy
do {
let result = try decoder.decode(Self.self, from: data)
return result
} catch {
debugPrint(error)
return nil
}
}
private static func data(from item: Any?) -> Data? {
switch item {
case let data as Data:
return data
case let string as String:
return string.data(using: .utf8)
case .some(let item):
return try? JSONSerialization.data(withJSONObject: item, options: [])
case nil:
return nil
}
}
}
使用上述功能解码的行是
let model = LocationCarModel.parse(from: data)
将poiList更改为标准swift数组,则不会发生错误。
有什么想法可以解决这个问题吗?任何帮助,将不胜感激。预先谢谢你。
答案 0 :(得分:1)
由于JSONDecoder不了解init(from:)
及其初始化方式,因此您需要对顶部结构拥有自己的NonEmpty
。除了初始化之外,我还添加了编码键和一个新错误
enum DecodeError: Error {
case arrayIsEmptyError
}
struct LocationCarModel: Codable {
var poiList: NonEmpty<[PointOfInterest]>
enum CodingKeys: String, CodingKey {
case poiList
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
let array = try container.decode([PointOfInterest].self, forKey: .poiList)
guard let first = array.first else {
throw DecodeError.arrayIsEmptyError
}
poiList = NonEmptyArray(first, array)
}
//...
}
答案 1 :(得分:0)
您可以尝试
struct Root: Codable {
let poiList: [PoiList]
}
// MARK: - PoiList
struct PoiList: Codable {
let id: Int
let coordinate: Coordinate
let fleetType: String
let heading: Double
}
// MARK: - Coordinate
struct Coordinate: Codable {
let latitude, longitude: Double
}
let res = try? JSONDecoder().decode(Root.self,from:data)
print(res)