Я играю с API New York Times и получаю сообщение
typeMismatch (Swift.Array, Swift.DecodingError.Context (codingPath: [CodingKeys (stringValue: "results",intValue: nil), _JSONKey (stringValue: «Index 3», intValue: 3), CodingKeys (stringValue: «multimedia», intValue: nil)], debugDescription: «Ожидается декодирование массива, но вместо этого найдена строка / данные.»,underError: nil))
Это происходит, когда мультимедийная часть JSON представляет собой строку, а не массив: аналогично этому вопросу SO:
Ожидается, что Swift Codableрасшифровать словарьно вместо этого нашел строку / данные
Поэтому я решил сделать минимальный пример.
Со статьей
public struct Article : Codable {
var abstract: String?
var thumbnail_standard: String?
var multimedia: [Multimedia]?
var title: String?
var url: URL?
private enum CodingKeys: String, CodingKey {
case abstract = "abstract"
case multimedia = "multimedia"
case thumbnail_standard = "thumbnail_standard"
case title = "title"
case url = "url"
}
}
и мультимедиа
struct Multimedia: Codable {
var url: String?
private enum CodingKeys: String, CodingKey {
case url = "url"
}
}
Я могу использовать строку JSON
let jsonString = """
{
"slug_name": "30dc-emoluments",
"section": "U.S.",
"subsection": "Politics",
"title": "Congressional Democrats’ Lawsuit Examining Trump’s Private Business Can Proceed, Federal Judge Says",
"abstract": "The decision is at least a temporary victory for the president’s critics who say he is willfully flaunting constitutional bans.",
"url": "https://www.nytimes.com/2019/04/30/us/politics/trump-emoluments-clauses.html",
"byline": "By SHARON LaFRANIERE",
"thumbnail_standard": "https://static01.nyt.com/images/2019/04/19/world/30dc-emoluments/30dc-emoluments-thumbStandard.jpg",
"item_type": "Article",
"source": "The New York Times",
"updated_date": "2019-04-30T22:09:45-04:00",
"created_date": "2019-04-30T21:56:05-04:00",
"published_date": "2019-04-29T20:00:00-04:00",
"first_published_date": "2019-04-30T21:54:34-04:00",
"material_type_facet": "News",
"kicker": null,
"subheadline": null,
"des_facet": "",
"org_facet": [
"Democratic Party",
"Constitution (US)",
"Justice Department",
"Trump International Hotel (Washington, DC)"
],
"per_facet": [
"Sullivan, Emmet G",
"Trump, Donald J"
],
"geo_facet": "",
"related_urls": [
{
"suggested_link_text": "Appeals Court Judges Appear Skeptical of Emoluments Case Against Trump",
"url": "https://www.nytimes.com/2019/03/19/us/politics/trump-emoluments-lawsuit.html"
},
{
"suggested_link_text": "Democrats in Congress Sue Trump Over Foreign Business Dealings",
"url": "https://www.nytimes.com/2017/06/14/us/politics/democrats-in-congress-to-sue-trump-over-foreign-business-dealings.html"
}
],
"multimedia": [
{
"url": "https://static01.nyt.com/images/2019/04/19/world/30dc-emoluments/30dc-emoluments-thumbStandard.jpg",
"format": "Standard Thumbnail",
"height": 75,
"width": 75,
"type": "image",
"subtype": "photo",
"caption": "The Trump International Hotel in Washington.",
"copyright": "Gabriella Demczuk for The New York Times"
},
{
"url": "https://static01.nyt.com/images/2019/04/19/world/30dc-emoluments/30dc-emoluments-articleInline.jpg",
"format": "Normal",
"height": 130,
"width": 190,
"type": "image",
"subtype": "photo",
"caption": "The Trump International Hotel in Washington.",
"copyright": "Gabriella Demczuk for The New York Times"
},
{
"url": "https://static01.nyt.com/images/2019/04/19/world/30dc-emoluments/30dc-emoluments-mediumThreeByTwo210.jpg",
"format": "mediumThreeByTwo210",
"height": 140,
"width": 210,
"type": "image",
"subtype": "photo",
"caption": "The Trump International Hotel in Washington.",
"copyright": "Gabriella Demczuk for The New York Times"
},
{
"url": "https://static01.nyt.com/images/2019/04/19/world/30dc-emoluments/30dc-emoluments-mediumThreeByTwo440.jpg",
"format": "mediumThreeByTwo440",
"height": 293,
"width": 440,
"type": "image",
"subtype": "photo",
"caption": "The Trump International Hotel in Washington.",
"copyright": "Gabriella Demczuk for The New York Times"
}
]
}
"""
с кодом:
if let data = jsonString.data(using: .utf8)
{
let decoder = JSONDecoder()
let result = try? decoder.decode(Article.self, from: data)
print(result)
}
Однако следующая строка JSON декодируется как nill:
let jsonString = """
{
"slug_name": "01a3_quote-web",
"section": "Today’s Paper",
"subsection": "",
"title": "Quotation of the Day: Who Killed Atlanta’s Children? Retesting Evidence After 40 Years",
"abstract": "Quotation of the Day for Wednesday, May 1, 2019.",
"url": "https://www.nytimes.com/2019/04/30/todayspaper/quotation-of-the-day-who-killed-atlantas-children-retesting-evidence-after-40-years.html",
"byline": "",
"thumbnail_standard": "",
"item_type": "Article",
"source": "The New York Times",
"updated_date": "2019-04-30T21:26:36-04:00",
"created_date": "2019-04-30T21:26:36-04:00",
"published_date": "2019-04-29T20:00:00-04:00",
"first_published_date": "2019-04-30T21:25:06-04:00",
"material_type_facet": "Quote",
"kicker": null,
"subheadline": null,
"des_facet": "",
"org_facet": "",
"per_facet": "",
"geo_facet": "",
"related_urls": null,
"multimedia": ""
}
"""
Несмотря на то, что я сделал свойства в своих объектах необязательными, они использовали .self в методе decoder.decode.
Как мне получить вторую строку JSON для декодирования?