无法将日期字符串转换为通过 JSONDecoder 通过 json 响应接收的日期格式

Unable to convert date string to Date format received through json response via JSONDecoder

我收到 'M/d/yy' 格式的日期(例如 21 年 8 月 13 日),我正在使用 JSONDecoder 将数据解码为预期模型。

struct Model: Codable {
    let submodel: SubModel
}

struct SubModel: Codable {
    let item1, item2: [Date: Int] // I used [String: Int] and it works but I don't want to write an
}                                 // additional method to do something that if possible can be
                                  // done easily

如果我使用 [String: Int] 格式,我可以让它工作,但如果我使用 [Date: Int],它就不能工作。我用解码器的dateEncodingStrategy设置自定义策略

makeGetRequest(url: url) { data in
    do {
        let decoder = JSONDecoder()
        decoder.dateDecodingStrategy = .custom({ decoder in
            let formatter = DateFormatter()
            let container = try decoder.singleValueContainer()
            let dateString = try container.decode(String.self)
            formatter.dateFormat = "M/d/yy"
            if let date = formatter.date(from: dateString) {
                return date
            }
            throw DecodingError.dataCorruptedError(in: container,
                                                   debugDescription: "Cannot decode date string \(dateString)")
        })
        let responseData = try decoder.decode(MainModel.self, from: data)
        success(responseData)
    } catch (let error) {
        debugPrint("Error decoding data: \(error.localizedDescription)")
        failure(error.localizedDescription)
    }
}

我从服务器获得的 json 格式的示例响应是

{
    "submodel": {
        "item1": {
            "8/7/21": 1,
            "8/8/21": 2,
            "8/9/21": 3
        },
        "item2": {
            "8/7/21": 11,
            "8/8/21": 12,
            "8/9/21": 13
        }
    }
}

我收到错误消息“无法读取数据,因为它的格式不正确。”

感谢任何帮助

除了为您的 SubModel 结构创建自定义解码器外,我认为您别无选择:

extension SubModel {
    init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        let dictionary1 = try container.decode([String:Int].self, forKey: .item1)
        let dictionary2 = try container.decode([String:Int].self, forKey: .item2)
        let formatter = DateFormatter()
        formatter.locale = .init(identifier: "en_US_POSIX")
        formatter.dateFormat = "M/d/yy"
        item1 = dictionary1.reduce(into: [:], { result, kv in
            guard let date = formatter.date(from: kv.key) else { return }
            result[date] = kv.value
        })
        item2 = dictionary2.reduce(into: [:], { result, kv in
            guard let date = formatter.date(from: kv.key) else { return }
            result[date] = kv.value
        })
    }
}