ios - swift 4 可编码 : Converting JSON return String to Int/Date/Float

标签 ios json swift swift4 codable

我正在研究一些项目并删除 JSON 解析框架,因为使用 Swift 4 似乎很简单。我遇到了这个奇怪的 JSON 返回,其中 IntsDates 作为 Strings 返回。

我看了GrokSwift's Parsing JSON with Swift 4 , Apple's website ,但我没有看到任何关于 re: changing types 的内容。

Apple's example code显示了如何更改 key 名称,但我很难弄清楚如何更改 key 类型。

这是它的样子:

{
    "WaitTimes": [
        {
            "CheckpointIndex": "1",
            "WaitTime": "1",
            "Created_Datetime": "10/17/2017 6:57:29 PM"
        },
        {
            "CheckpointIndex": "2",
            "WaitTime": "6",
            "Created_Datetime": "10/12/2017 12:28:47 PM"
        },
        {
            "CheckpointIndex": "0",
            "WaitTime": "8",
            "Created_Datetime": "9/26/2017 5:04:42 AM"
        }
    ]
}

我使用 CodingKey 将字典键重命名为符合 Swift 的条目,如下所示:

struct WaitTimeContainer: Codable {
  let waitTimes: [WaitTime]

  private enum CodingKeys: String, CodingKey {
    case waitTimes = "WaitTimes"
  }

  struct WaitTime: Codable {
    let checkpointIndex: String
    let waitTime: String
    let createdDateTime: String

    private enum CodingKeys: String, CodingKey {
      case checkpointIndex = "CheckpointIndex"
      case waitTime = "WaitTime"
      case createdDateTime = "Created_Datetime"
    }
  }
}

这仍然给我留下了 String,它应该是 IntDate。我将如何使用可编码协议(protocol)?

最佳答案

这是 not yet possible因为 Swift 团队在 JSONDecoder 中只提供了 String to date 解码器。

不过您始终可以手动解码:

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"
        }
    }
}

关于ios - swift 4 可编码 : Converting JSON return String to Int/Date/Float,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46901445/

相关文章:

ios - 如何为 CAlayer 的边界设置动画以逐渐显示图像?

iphone - 如何使用 ios sdk 从地址簿创建 vCard?

java.lang.AssertionError : expected: org. json.JSONObject< {"feedback":[]}> but was: org. json.JSONObject< {"feedback":[]}>

ios - 以编程方式添加的自定义 UIBarButtonItem 不遵循 tintColor

ios - 如何使用 swift 在 iOS7 中调用 CLLocation Manager 委托(delegate)方法

ios - 在 Adob​​e Flash Pro 中设计的应用程序在 iOS 设备上的动画滞后

json - json格式无效,请检查。原因 : invalid character 'a' looking for beginning of object key string

javascript - 访问 JSON 中的嵌套数组对象和值

swift - 有没有办法在Interface Builder中选择tintColor?

ios - 如何在 CollectionView 中更快地加载 JSON 图像 url