简体   繁体   English

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

[英]Can MKGeoJSONDecoder be extended to parse ISO8601 dates like JSONDecoder?

I have GeoJSON data from an API and it contains dates that are in ISO8601 format.我有来自 API 的 GeoJSON 数据,它包含 ISO8601 格式的日期。 I can decode them in SwiftUI as a string and manipulate them through a calculated field to get a version that is type Date but it's clumsy.我可以在 SwiftUI 中将它们解码为字符串,并通过计算字段对它们进行操作以获得日期类型的版本,但它很笨拙。 I know the JSONDecoder supports date en/decoding options and I'd like the same behaviour.. similar to this:我知道 JSONDecoder 支持日期编码/解码选项,我想要相同的行为..类似于:

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

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

I was thinking of maybe an extension to MKGeoJSONDecoder but I can't figure out how to even get started because of the need to be in the parsing flow.我在考虑 MKGeoJSONDecoder 的扩展,但由于需要进入解析流程,我什至无法弄清楚如何开始。

Thoughts?想法? Thanks谢谢

Thanks vadian, all of the data I wanted was in the properties attribute so there was really no value in using MKGeoJSONDecoder.谢谢 vadian,我想要的所有数据都在 properties 属性中,所以使用 MKGeoJSONDecoder 真的没有任何价值。 I just switched to normal JSONDecoder and put a custom ISO8601 formatter to match my data and all works great.我刚刚切换到普通的 JSONDecoder 并放置了一个自定义的 ISO8601 格式化程序来匹配我的数据并且一切正常。

In case anyone wants to reference, here is the playground code.如果有人想参考,这里是游乐场代码。 You'd want to add a bunch of error checking of course.你当然想添加一堆错误检查。 And thanks to Sarunw for the great info on the custom date decoding ( https://sarunw.com/posts/how-to-parse-iso8601-date-in-swift/ )感谢 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)")
    }
}

Output is the date/times of the most recent surface weather observations for Flin Flon, Manitoba: Output 是马尼托巴省 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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM