Я добавлю еще один ответ, даже если StackOverflow посоветует мне отредактировать предыдущий ответ, но я не могу не заметить, что добавление ваших «новых» неразобранных данных в основном превращает этот вопрос в совершенно другой. Обычно вам следует задать другой вопрос и, возможно, оставить комментарий, который вы хотели бы продолжить в другом вопросе. Достаточно мета, теперь для ответа.
Хотя ваши «неразобранные данные» технически верны, они по-прежнему очень неудобны в двух отношениях. Линеаризованные необязательные параметры в конечном итоге будут экранированы, поэтому все ваши двойные кавычки будут экранированы (и в правильном JSON их будет множество), и не будет новых строк, которые трудно прочитать в StackOverflow, где вы должны постараться сохранить свои строки не слишком намного больше ширины типичного окна браузера. Об избежавших двойных кавычках можно позаботиться, просто развернув необязательные (с !
), но добавить красивые новые строки немного сложнее. Однако, поскольку ваш JSON теперь в основном верен, я могу использовать его, чтобы показать некоторые другие тонкости протокола Codable
. Если вы запустите эту игровую площадку:
import Cocoa
let string = "{\"activities-steps\":[{\"dateTime\":\"2018-04-17\",\"value\":\"7170\"},{\"dateTime\":\"2018-04-18\",\"value\":\"6443\"},{\"dateTime\":\"2018-04-19\",\"value\":\"11254\"},{\"dateTime\":\"2018-04-20\",\"value\":\"5771\"},{\"dateTime\":\"2018-04-21\",\"value\":\"33\"},{\"dateTime\":\"2018-04-22\",\"value\":\"2697\"},{\"dateTime\":\"2018-04-23\",\"value\":\"11\"},{\"dateTime\":\"2018-04-24\",\"value\":\"8\"},{\"dateTime\":\"2018-04-25\",\"value\":\"0\"},{\"dateTime\":\"2018-04-26\",\"value\":\"0\"},{\"dateTime\":\"2018-04-27\",\"value\":\"0\"},{\"dateTime\":\"2018-04-28\",\"value\":\"389\"},{\"dateTime\":\"2018-04-29\",\"value\":\"4916\"},{\"dateTime\":\"2018-04-30\",\"value\":\"0\"},{\"dateTime\":\"2018-05-01\",\"value\":\"0\"},{\"dateTime\":\"2018-05-02\",\"value\":\"0\"},{\"dateTime\":\"2018-05-03\",\"value\":\"0\"},{\"dateTime\":\"2018-05-04\",\"value\":\"1929\"},{\"dateTime\":\"2018-05-05\",\"value\":\"0\"},{\"dateTime\":\"2018-05-06\",\"value\":\"0\"},{\"dateTime\":\"2018-05-07\",\"value\":\"0\"},{\"dateTime\":\"2018-05-08\",\"value\":\"2818\"},{\"dateTime\":\"2018-05-09\",\"value\":\"6990\"},{\"dateTime\":\"2018-05-10\",\"value\":\"6558\"},{\"dateTime\":\"2018-05-11\",\"value\":\"15434\"},{\"dateTime\":\"2018-05-12\",\"value\":\"0\"},{\"dateTime\":\"2018-05-13\",\"value\":\"0\"},{\"dateTime\":\"2018-05-14\",\"value\":\"0\"},{\"dateTime\":\"2018-05-15\",\"value\":\"0\"},{\"dateTime\":\"2018-05-16\",\"value\":\"0\"},{\"dateTime\":\"2018-05-17\",\"value\":\"0\"}]}"
let jsonData = string.data(using: .utf8)!
struct Step: Codable {
let value: String
let dateTime : Date
}
struct Activity: Codable {
let steps: [Step]
enum CodingKeys: String, CodingKey {
case steps = "activities-steps"
}
}
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-mm-dd"
let decoder = JSONDecoder()
decoder.dateDecodingStrategy = .formatted(formatter)
do {
let activity = try decoder.decode(Activity.self, from: jsonData)
let encoder = JSONEncoder()
encoder.dateEncodingStrategy = .formatted(formatter)
encoder.outputFormatting = .prettyPrinted
let data = try encoder.encode(activity)
print(String(data: data, encoding: .utf8)!)
} catch {
print(error)
}
Это напечатает следующий довольно напечатанный JSON:
{
"activities-steps" : [
{
"value" : "7170",
"dateTime" : "2018-04-17"
},
{
"value" : "6443",
"dateTime" : "2018-04-18"
},
{
"value" : "11254",
"dateTime" : "2018-04-19"
},
{
"value" : "5771",
"dateTime" : "2018-04-20"
},
{
"value" : "33",
"dateTime" : "2018-04-21"
},
{
"value" : "2697",
"dateTime" : "2018-04-22"
},
{
"value" : "11",
"dateTime" : "2018-04-23"
},
{
"value" : "8",
"dateTime" : "2018-04-24"
},
{
"value" : "0",
"dateTime" : "2018-04-25"
},
{
"value" : "0",
"dateTime" : "2018-04-26"
},
{
"value" : "0",
"dateTime" : "2018-04-27"
},
{
"value" : "389",
"dateTime" : "2018-04-28"
},
{
"value" : "4916",
"dateTime" : "2018-04-29"
},
{
"value" : "0",
"dateTime" : "2018-04-30"
},
{
"value" : "0",
"dateTime" : "2018-05-01"
},
{
"value" : "0",
"dateTime" : "2018-05-02"
},
{
"value" : "0",
"dateTime" : "2018-05-03"
},
{
"value" : "1929",
"dateTime" : "2018-05-04"
},
{
"value" : "0",
"dateTime" : "2018-05-05"
},
{
"value" : "0",
"dateTime" : "2018-05-06"
},
{
"value" : "0",
"dateTime" : "2018-05-07"
},
{
"value" : "2818",
"dateTime" : "2018-05-08"
},
{
"value" : "6990",
"dateTime" : "2018-05-09"
},
{
"value" : "6558",
"dateTime" : "2018-05-10"
},
{
"value" : "15434",
"dateTime" : "2018-05-11"
},
{
"value" : "0",
"dateTime" : "2018-05-12"
},
{
"value" : "0",
"dateTime" : "2018-05-13"
},
{
"value" : "0",
"dateTime" : "2018-05-14"
},
{
"value" : "0",
"dateTime" : "2018-05-15"
},
{
"value" : "0",
"dateTime" : "2018-05-16"
},
{
"value" : "0",
"dateTime" : "2018-05-17"
}
]
}
Теперь это по-прежнему громоздко как вопрос StackOverflow (обычно вам, вероятно, следует уменьшить его, так как это просто скучное повторение, но это нормально для первого вопроса), но в этой форме все еще намного легче переварить. И, надеюсь, он научил вас, как создавать Codable
структуры для представления ваших данных в действительно Swifty форме и как отформатировать какой-то грязный JSON в более читаемый формат, который легче усваивается вашими глазами.
Очевидно, что JSON был прав, поскольку JSONDecoder
удалось его проанализировать, но вам, как человеку, гораздо проще судить, как он должен выглядеть, когда вы видите его в довольно печатной форме.
Таким образом, ваш activity
должен быть прост в обработке и использовать его в TableView
, поэтому я надеюсь, что по крайней мере некоторые ваши проблемы были решены этим.