Swift 4 Codable: Converting JSON return String to Int/Date/Float

后端 未结 2 1493
没有蜡笔的小新
没有蜡笔的小新 2020-12-31 12:15

I\'m going through some projects and removing JSON parsing frameworks, as it seems pretty simple to do with Swift 4. I\'ve encountered this oddball JSON return where I

相关标签:
2条回答
  • 2020-12-31 12:15
    public extension KeyedDecodingContainer {
    public func decode(_ type: Date.Type, forKey key: Key) throws -> Date {
        let dateString = try self.decode(String.self, forKey: key)
        let dateFormatter = DateFormatter()
        dateFormatter.dateFormat = "MM/dd/yyyy hh:mm:ss a"
        guard let date = dateFormatter.date(from: dateString) else {
            let context = DecodingError.Context(codingPath: codingPath,
                                                debugDescription: "Could not parse json key to a Date")
            throw DecodingError.dataCorrupted(context)
        }
        return date
    }
    }
    

    Usage: -

    let date: Date = try container.decode(Date.self, forKey: . createdDateTime)
    
    0 讨论(0)
  • 2020-12-31 12:39

    This is not yet possible as Swift team has provided only String to date decoder in JSONDecoder.

    You can always decode manually though:

    struct WaitTimeContainer: Decodable {
        let waitTimes: [WaitTime]
    
        private enum CodingKeys: String, CodingKey {
            case waitTimes = "WaitTimes"
        }
    
        struct WaitTime:Decodable {
            let checkpointIndex: Int
            let waitTime: Float
            let createdDateTime: Date
    
            init(checkpointIndex: Int, waitTime: Float, createdDateTime:Date) {
                self.checkpointIndex = checkpointIndex
                self.waitTime = waitTime
                self.createdDateTime = createdDateTime
            }
    
            static let formatter: DateFormatter = {
                let formatter = DateFormatter()
                formatter.calendar = Calendar(identifier: .iso8601)
                formatter.locale = Locale(identifier: "en_US_POSIX")
                formatter.timeZone = TimeZone(secondsFromGMT: 0)
                formatter.dateFormat = "MM/dd/yyyy hh:mm:ss a"
                return formatter
            }()
    
            init(from decoder: Decoder) throws {
                let container = try decoder.container(keyedBy: CodingKeys.self)
                let checkpointIndexString = try container.decode(String.self, forKey: .checkpointIndex)
                let checkpointIndex = Int(checkpointIndexString)!
    
                let waitTimeString = try container.decode(String.self, forKey: .waitTime)
                let waitTime = Float(waitTimeString)!
    
                let createdDateTimeString =  try container.decode(String.self, forKey: .createdDateTime)
    
                let createdDateTime = WaitTime.formatter.date(from: createdDateTimeString)!
    
                self.init(checkpointIndex:checkpointIndex, waitTime:waitTime, createdDateTime:createdDateTime)
            }
    
            private enum CodingKeys: String, CodingKey {
                case checkpointIndex = "CheckpointIndex"
                case waitTime = "WaitTime"
                case createdDateTime = "Created_Datetime"
            }
        }
    }
    
    0 讨论(0)
提交回复
热议问题