Swift и iso8601 попробуйте разобрать "HH: mm: ss" - PullRequest
0 голосов
/ 28 сентября 2018

Мы использовали Decodable, и у нас есть поле time: Date, но с сервера пришло только время в формате «ЧЧ: мм: сс».Еще один синтаксический анализатор дат с DateInRegion.

Но это приложение сбоя поля я пытаюсь сделать что-то в декодере, но не вижу никаких свойств (.count), и я не знаю, что нужно делать

let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .custom({ decoder -> Date in
  do {
    let value = try decoder.singleValueContainer()
    let string = try value.decode(String.self)
    if string.conut == 8 {
        if let date = DateInRegion(
            string: string,
            format: .iso8601(options: .withTime),
            fromRegion: Region.Local()
            ) {
            return date.absoluteDate
        } else {
            throw DecodingError.nil
        }
    } else if let date = DateInRegion(
      string: string,
      format: .iso8601(options: .withInternetDateTime),
      fromRegion: Region.Local()
      ) {
      return date.absoluteDate
    } else {
      throw DecodingError.nil
    }
  } catch let error {

1 Ответ

0 голосов
/ 28 сентября 2018

Не уверен, что вы пытаетесь достичь, но, похоже, вы хотите обработать несколько форматов даты в одном JSON-декодере.

С учетом структуры ответа Decodable:

struct Response: Decodable {
  var time: Date
  var time2: Date
}

Вы можете настроить декодер так, чтобы он обрабатывал все необходимые форматы даты:

let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .custom({ (decoder) -> Date in
  // Extract string date from the container
  let container = try decoder.singleValueContainer()
  let stringDate = try container.decode(String.self)

  // Trying to parse the "HH:mm:ss" format
  let dateFormatter = DateFormatter()
  dateFormatter.dateFormat = "HH:mm:ss"
  if let date = dateFormatter.date(from: stringDate) {
    return date // successfully parsed "HH:mm:ss" format
  }

  // Trying to parse the iso8601 format
  if let date = ISO8601DateFormatter().date(from: stringDate) {
    return date // successfully parsed iso8601 format.
  }

  // Unknown date format, throw an error.
  let context = DecodingError.Context(codingPath: [], debugDescription: "Unable to parse a date from '\(stringDate)'")
  throw DecodingError.dataCorrupted(context)
})

Примечание: Это пример кода, и он не очень оптимизирован (DateFormatter init каждый разВы хотите проанализировать дату, используя синтаксический анализ методом грубой силы, чтобы определить, имеет ли дата формат «ЧЧ: мм: сс» или нет, ...).

Я думаю, лучший способ оптимизировать это, состоит в том, чтобы использовать несколько декодеров, каждый из которых настроен на определенный формат даты, и использовать правильный, когда это необходимо.Например, если вы пытаетесь проанализировать JSON из API, вы должны определить, нужно ли анализировать формат iso8601 или что-то еще, и соответственно использовать правильный декодер.

Вот примердекодера, работающего на детской площадке:

let json = """
{"time": "11:05:45", "time2": "2018-09-28T16:02:55+00:00"}
"""

let response = try! decoder.decode(Response.self, from: json.data(using: .utf8)!)
response.time // Jan 1, 2000 at 11:05 AM
response.time2 // Sep 28, 2018 at 6:02 PM
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...