import Foundation
let json = """
[{
"idSite": 204233,
"status": 0,
"Name": "",
"timeOfStatus": null
},
{
"idSite": 204234,
"status": 0,
"Name": "",
"timeOfStatus": null
},
{
"idSite": 204235,
"status": 0,
"Name": "",
"timeOfStatus": null
},
{
"idSite": 204236,
"status": 1,
"Name": "OK",
"timeOfStatus": "2019-06-26 12:58:16"
}]
"""
struct SomeStruct: Decodable {
let idSite: Int
let status: Bool
let name: String
let timeOfStatus: Date?
// Преобразуем Name -> name
private enum CodingKeys: String, CodingKey {
case idSite
case status
case name = "Name"
case timeOfStatus
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.idSite = try container.decode(Int.self, forKey: .idSite)
// Выбрасываем ошибку, если статус не равен 1. Не выделяем зря память.
let status = try container.decode(Int.self, forKey: .status)
if status == 1 {
self.status = true
} else {
throw DecodingError.dataCorruptedError(forKey: .status, in: container, debugDescription: "Status mast be `1`")
}
self.name = try container.decode(String.self, forKey: .name)
// Преобразуем строку с датой в объект для работы с датами Date
let date = try? container.decode(String.self, forKey: .timeOfStatus)
let dateFormatter: DateFormatter = {
$0.dateFormat = "yyyy-MM-dd HH:mm:ss"
$0.calendar = Calendar(identifier: .iso8601)
$0.timeZone = TimeZone(secondsFromGMT: 0)
$0.locale = Locale(identifier: "en_US_POSIX")
return $0
}(DateFormatter())
self.timeOfStatus = date != nil ? dateFormatter.date(from: date!) : nil
}
}
// Тип обёртка, которая даст легко отфильтровать данные, от тех, которые не прошли из-за статуса.
enum Throwable<T: Decodable>: Decodable {
case success(T), failure(Error)
init(from decoder: Decoder) throws {
do {
let decoded = try T(from: decoder)
self = .success(decoded)
} catch let error {
self = .failure(error)
}
}
var value: T? {
switch self {
case .failure(_):
return nil
case .success(let value):
return value
}
}
}
let decoder = JSONDecoder()
let arrayOfSomeStructs = try! decoder.decode([Throwable<SomeStruct>].self, from: json.data(using: .utf8)!)
let filteredArrayOfSomeStructs = arrayOfSomeStructs.compactMap{ $0.value }
print(filteredArrayOfSomeStructs.count)