可以扩展 MKGeoJSONDecoder 以像 JSONDecoder 一样解析 ISO8601 日期吗?

Can MKGeoJSONDecoder be extended to parse ISO8601 dates like JSONDecoder?

我有来自 API 的 GeoJSON 数据,它包含 ISO8601 格式的日期。我可以在 SwiftUI 中将它们解码为字符串,并通过计算字段对它们进行操作以获得 Date 类型的版本,但它很笨拙。 我知道 JSONDecoder 支持日期 en/decoding 选项,我想要相同的行为..类似于:

let encoder = JSONEncoder()
encoder.dateEncodingStrategy = .iso8601

let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .iso8601

我正在考虑 MKGeoJSONDecoder 的扩展,但由于需要进入解析流程,我什至不知道如何开始。

想法?谢谢

谢谢 vadian,我想要的所有数据都在 properties 属性中,所以使用 MKGeoJSONDecoder 真的没有任何价值。我刚刚切换到普通的 JSONDecoder 并放置了一个自定义的 ISO8601 格式化程序来匹配我的数据并且一切正常。

如果有人想参考,这里是 playground 代码。你当然想添加一堆错误检查。感谢 Sarunw 提供有关自定义日期解码的重要信息 (https://sarunw.com/posts/how-to-parse-iso8601-date-in-swift/)

import Foundation
import MapKit

struct Response: Codable {
    let features: [Feature]
}

struct Feature: Codable {
    let properties: Properties
}

struct Properties: Codable {
    let stnNamValue: String?
    let dateTmValue: Date?
    
    enum CodingKeys: String, CodingKey {
        case stnNamValue = "stn_nam-value"
        case dateTmValue = "date_tm-value"
    }
}

Task {
    // get the data from API
    let url = URL(string: "https://api.weather.gc.ca/collections/swob-realtime/items?f=json&sortby=-date_tm-value&clim_id-value=5050919&limit=3")
    let (data, _) = try await URLSession.shared.data(from: url!)
    
    // create the decoder with custom ISO8601 formatter
    let decoder = JSONDecoder()
    let formatter = ISO8601DateFormatter()
    formatter.formatOptions = [.withFullDate, .withFullTime,.withFractionalSeconds, .withTimeZone]
    decoder.dateDecodingStrategy = .custom({ decoder in
        let container = try decoder.singleValueContainer()
        let dateString = try container.decode(String.self)
        if let date = formatter.date(from: dateString) {return date}
        throw DecodingError.dataCorruptedError(in: container, debugDescription: "Cannot decode date string \(dateString)")
    })
    
    // decode & print the results
    let decodedResponse = try decoder.decode(Response.self, from: data)
    decodedResponse.features.forEach {(feature) in
        print("Station: \(feature.properties.stnNamValue ?? "<no value>"), Date: \(feature.properties.dateTmValue)")
    }
}

输出是 date/times 马尼托巴省 Flin Flon 的最新地面天气观测结果:

Station: FLIN FLON, Date: Optional(2022-02-16 12:22:00 +0000)
Station: FLIN FLON, Date: Optional(2022-02-16 12:21:00 +0000)
Station: FLIN FLON, Date: Optional(2022-02-16 12:20:00 +0000)