Возможно ли еще использовать Decodable с метками времени / датами Firestore? - PullRequest
0 голосов
/ 28 ноября 2018

У меня есть словарь, который [String: Bookmark], но созданный, он сохраняется как Timestamp, и декодер выдает ошибку при попытке разобраться в Date

***Завершение работы приложения из-за необработанного исключения «NSInvalidArgumentException», причина: «Неверный тип в записи JSON (__NSDate)»

struct Bookmark: Decodable {
    let messageId: String
    let messageCreatedAt: Date
}


JSONDecoder().decode([String: Bookmark].self, data: data)

Есть ли еще способ заставить протокол Swift Decodable работать с Firestore?Временные метки?

Редактировать:

Если я напечатаю [String: Any], а затем попробую декодировать в консоли, вот так:

 ▿ 1 : 2 elements
    - key : "messageCreatedAt"
    - value : 2018-11-27 20:59:11 +0000

po valueDict["messageCreatedAt"] as? Date

Я получу

▿ Optional<Date>
  ▿ some : 2018-11-27 20:59:11 +0000
    - timeIntervalSinceReferenceDate : 565045151.531769

Значит, в Decodable должно быть что-то, что не в состоянии идентифицировать и проанализировать это?

Редактировать:

JSON равно

{
  "messageId": "abc123",
  "messageCreatedAt": "2018-11-27 20:59:11 +0000"
}

1 Ответ

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

Как JSONDecoder означает, что даты декодирования определяются значением свойства .dateDecodingStrategy.

Если вам нужно проанализировать Date из строки, вы должны использовать либо .iso8601 или .formatted(_:) (или если ваш формат даты действительно нестандартный, сложный и / или странный, вы можете использовать .custom(_:)).

Ваша строка даты почти ISO 8601 отформатирована (ей не хватает только T между датой и временем), но этого достаточно для сбоя.

Так что ваш лучший вариант здесь - использовать formatted(_:):

// Declare it somewhere and reuse single instance as much as possible, formatter initialization is quite expensive
let dateFormatter = DateFormatter()
dateFormatter.locale = Locale(identifier: "en_US_POSIX") // Better to fix Locale here
dateFormatter.dateFormat = "yyyy-MM-dd kk:mm:ss Z"

А потом

let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(dateFormatter)
let bookmark = try decoder.decode(Bookmark.self, from: data) 

print(bookmark.messageCreatedAt, bookmark.messageCreatedAt.timeIntervalSince1970)
// prints "2018-11-27 20:59:11 +0000 1543352351.0"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...