Swift 4 Кодируемое декодирование JSON
Я пытаюсь реализовать новое Codable
протокол, поэтому я добавил Codable
к моей структуре, но я застрял на декодировании JSON.
Вот что у меня было раньше:
Структура -
struct Question {
var title: String
var answer: Int
var question: Int
}
Клиент -
...
guard let data = data else {
return
}
do {
self.jsonResponse = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: Any]
let questionItems = self.jsonResponse?["themes"] as! [[String: Any]]
questionItems.forEach {
let item = Question(title: $0["title"] as! String,
answer: $0["answer"] as! Int,
question: $0["question"] as! Int)
questionData.append(item)
}
} catch {
print("error")
}
Вот что у меня сейчас, кроме как я не могу разобраться с частью декодера:
Структура -
struct Question: Codable {
var title: String
var answer: Int
var question: Int
}
Клиент -
...
let decoder = JSONDecoder()
if let questions = try? decoder.decode([Question].self, from: data) {
// Can't get past this part
} else {
print("Not working")
}
Это печатает "Не работает", потому что я не могу пройти decoder.decode
часть. Есть идеи? По мере необходимости разместим дополнительный код, спасибо!
РЕДАКТИРОВАТЬ:
Пример API JSON:
{
"themes": [
{
"answer": 1,
"question": 44438222,
"title": "How many letters are in the alphabet?"
},
{
"answer": 0,
"question": 44438489,
"title": "This is a random question"
}
]
}
Если я распечатаю self.jsonResponse
Я получаю это:
Optional(["themes": <__NSArrayI 0x6180002478f0>(
{
"answer" = 7;
"question" = 7674790;
title = "This is the title of the question";
},
{
"answer_" = 2;
"question" = 23915741;
title = "This is the title of the question";
}
Мой новый код:
struct Theme: Codable {
var themes : [Question]
}
struct Question: Codable {
var title: String
var answer: Int
var question: Int
}
...
if let decoded = try? JSONDecoder().decode(Theme.self, from: data) {
print("decoded:", decoded)
} else {
print("Not working")
}
3 ответа
Если ваш JSON имеет структуру
{"themes" : [{"title": "Foo", "answer": 1, "question": 2},
{"title": "Bar", "answer": 3, "question": 4}]}
вам нужен эквивалент для themes
объект. Добавить эту структуру
struct Theme : Codable {
var themes : [Question]
}
Теперь вы можете декодировать JSON:
if let decoded = try? JSONDecoder().decode(Theme.self, from: data) {
print("decoded:", decoded)
} else {
print("Not working")
}
Содержащие Question
объекты декодируются неявно.
Вы получаете эту ошибку, потому что ваш JSON скорее всего структурирован так:
{
"themes": [
{ "title": ..., "question": ..., "answer": ... },
{ "title": ..., "question": ..., "answer": ... },
{ ... }
],
...
}
Однако код, который вы написали, ожидает [Question]
на верхнем уровне. Вам нужен другой тип верхнего уровня, который имеет themes
свойство, которое является [Question]
, Когда вы декодируете этот тип верхнего уровня, ваш [Question]
будет декодирован для themes
ключ.
Здравствуйте @all Я добавил код для кодирования и декодирования JSON для Swift 4.
Пожалуйста, используйте ссылку здесь