Я рассмотрел пару вопросов и ответов здесь, по SO, и хотя они похожи на мой вопрос, они не совсем решают мою проблему, поскольку я пробовал их кучу, но это не работает. Вот мой json и метод, который я пробовал, и я все время получаю сообщение об ошибке «Данные не могут быть прочитаны, потому что они имеют неправильный формат».
{
"status": 1,
"errorMsg": "success",
"data": [
{
"id": null,
"subMenuId": null,
"type": "Coming Feat",
"data": {
"link": "/google.com",
"title": "Google",
"shortDescription": "This is fun",
"imageUrl": "",
"openInNewWindow": false
},
"datas": null,
"component": null
},
{
"id": "wdub208t2ghf0b",
"subMenuId": "39g3hvb83hb98hv",
"type": "GoingEvent",
"data": {
"eventId": "983gv83hv8hv38",
"sessionId": null,
"title": "Fest",
"iconMarker": "http://google.com/sites.png",
"isPaid": false,
"startDT": "2018-07-18T16:00:00Z",
"endDT": "2018-10-31T22:00:00Z",
"subTitle": null,
"startDate": "Oct, 2018",
"endDate": "Oct, 2018",
"openTime": "04:00 PM",
"closeTime": "10:00 PM",
"thumbnail": "https://static.visit.com/estival23.jpg",
"verticalFeaturedImageUrl": "",
"horizontalImageUrl": "",
"categoryTitle": "Celebration",
"eventCategories": [
"394bf3w9fbv93v8",
"dhvbwuehv80"
],
"locations": [
{
"uniqueName": "fest",
"title": "Got if",
"area": "",
"region": "Put it",
"latitude": 67.14517,
"longitude": 78.797733,
"distance": "N/A",
"startDate": "2018-07-18T16:00:00",
"endDate": "2018-07-27T22:00:00",
"distancevalue": 0,
"duration": "N/A",
"durationValue": 0,
"valid": true,
"hasSet": false
}
],
"prices": null
},
"datas": null,
"component": null
}
]
}
class FeatureData: Decodable {
var link: String?
var title: String?
var shortDescription: String?
var imageUrl: String?
enum CodingKeys: String, CodingKey {
case link
case title
case shortDescription
case imageUrl
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
link = try container.decode(String.self, forKey: .link)
title = try container.decode(String.self, forKey: .title)
shortDescription = try container.decode(String.self, forKey:
.shortDescription)
imageUrl = try container.decode(String.self, forKey: .imageUrl)
}
init() {
}
}
class FeedFeature: Decodable {
var id: String?
var subMenuId: String?
var type: String?
var data = HomeFeedFeatureData()
enum Codingkeys: String, CodingKey {
case id
case subMenuId
case type
case data
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: Codingkeys.self)
id = try container.decode(String.self, forKey: .id)
subMenuId = try container.decode(String.self, forKey: .subMenuId)
type = try container.decode(String.self, forKey: .type)
data = try container.decode(HomeFeedFeatureData.self, forKey:
.data)
}
init() {
}
}
class EventCalendar: Decodable {
// MARK: Properties
var eventId: String = ""
var sessionId: String = ""
var title: String = ""
var iconMarker: String?
var isPaid: Bool = false
var startDT: String = ""
var endDT: String = ""
var subTitle: String = ""
var startDate: String = ""
var endDate: String = ""
var openTime: String = ""
var closeTime: String = ""
var thumbnail: String = ""
var locations: [EventLocation] = []
var prices: [Price]?
var categoryTitle: String = ""
var isLoadingCell: Bool = false
var isSelected: Bool = false
enum CodingKeys: String, CodingKey {
case eventId = "eventId"
case sessionId = "sessionId"
case title = "title"
case iconMarker = "iconMarker"
case isPaid = "isPaid"
case startDT = "startDT"
case endDT = "endDT"
case subTitle = "subTitle"
case startDate = "startDate"
case endDate = "endDate"
case openTime = "openTime"
case closeTime = "closeTime"
case thumbnail = "thumbnail"
case locations = "locations"
case prices = "prices"
case categoryTitle = "categoryTitle"
}
init() {}
// MARK: Methods
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
eventId = try container.decode(String.self, forKey: .eventId)
sessionId = try container.decodeIfPresent(String.self, forKey:
.sessionId) ?? ""
title = try container.decodeIfPresent(String.self, forKey: .title)
?? ""
iconMarker = try container.decodeIfPresent(String.self, forKey:
.iconMarker) ?? ""
isPaid = try container.decodeIfPresent(Bool.self, forKey: .isPaid)
?? false
startDT = try container.decodeIfPresent(String.self, forKey:
.startDT) ?? ""
endDT = try container.decodeIfPresent(String.self, forKey: .endDT)
?? ""
subTitle = try container.decodeIfPresent(String.self, forKey:
.subTitle) ?? ""
startDate = try container.decodeIfPresent(String.self, forKey:
.startDate) ?? ""
endDate = try container.decodeIfPresent(String.self, forKey:
.endDate) ?? ""
openTime = try container.decodeIfPresent(String.self, forKey:
.openTime) ?? ""
closeTime = try container.decodeIfPresent(String.self, forKey:
.closeTime) ?? ""
thumbnail = try container.decodeIfPresent(String.self, forKey:
.thumbnail) ?? ""
locations = try container.decodeIfPresent([EventLocation].self,
forKey: .locations) ?? []
categoryTitle = try container.decodeIfPresent(String.self, forKey:
.categoryTitle) ?? ""
// Remove duplicate/invaid prices - The same logic as
EventMapComponent
if let tempPrice = try container.decode([Price]?.self, forKey:
.prices) {
var uniquePrices: [Price] = []
for price in tempPrice {
if !uniquePrices.contains(where: { (checkPrice) -> Bool in
checkPrice.priceInfo == price.priceInfo &&
checkPrice.value == price.value &&
checkPrice.currencyCode == price.currencyCode
}),
price.priceInfo.count > 0 &&
price.value.count > 0 &&
price.currencyCode.count > 0 &&
price.bookingUrl.count > 0 {
// Filter for 0 value prices
if let priceValue = Double(price.value), priceValue > 0
{
uniquePrices.append(price)
}
}
}
prices = uniquePrices
}
isSelected = BookMarkManager.shared.isFavoriteItem(by: eventId)
}
}
Да, я проверил и просто не мог понять, откуда взялась проблема. Я знаю это многое, но любая помощь будет принята с благодарностью @JoakimDanielson
Ваши данные, подобные JSON, не являются действительным JSON. Многие брекеты {} и брекеты [] не уравновешивают. Если это действительно те данные, которые вы получаете, вы не можете проанализировать их с помощью других библиотек JSON. Пожалуйста, попробуйте найти правильный JSON, который у вас должен быть. С текущими данными, подобными JSON, вам очень сложно помочь.
Ваш JSON недействителен. Где код для EventLocation, HomeFeedFeaturedData и Price?
Ваш JSON действителен. Как я вижу, «данные» различаются для каждого объекта. В первой записи указаны FeatureData, а во второй - HomeFeedFeatureData. В своем коде вы определяете EventCalendar, но где вы его используете? Вы должны проверить, является ли это FeatureData или HomeFeedFeatureData.
Не печатайте error.localizedDescription, распечатайте экземпляр error. Ошибка сообщает вам, что именно не так. И вы можете удалить CodingKeys, если они соответствуют именам членов структуры.
@codeperfect, можете ли вы предоставить код, который вызывает метод decode экземпляра JSONDecoder?

В вашем коде много неправильного. Просмотрите мой список ниже, делайте это шаг за шагом, и вы обнаружите, что это намного проще, чем вы это делаете.
let, а не var, и не задавайте им начальные значения.FeedFeature должен иметь id, чтобы быть действительным, объявите let id: String.let subTitle: String?)startDT - это Date, поэтому объявите как let startDT: Date (или Date?, если это необязательно). Вы можете преобразовать форматированные даты String в значения Date, установив dateDecodingStrategy. Используйте URL, а не String, например, let thumbnail: URL?,init(from decoder: Decoder).init - вы сможете делать все вышеперечисленное без кода любой, кроме деклараций. Вы можете сделать это после инициализации структуры (возможно, использовать временный объект для декодирования, а затем скопировать в другой вместе с де-дублированием)Вы можете легко проверить это на детской площадке. Просто начни с…
let data = """
{your json}
"""".data(using: .utf8)!
struct Response: Decodable {
let status: Int
let errorMsg: String
let data: [FeedFeature]
}
struct FeedFeature: Decodable {
}
JSONDecoder().decode([Response.self], from: data)
а затем постепенно наращивайте свои объекты, добавляя свойства по одному или несколько за раз.
Это много json и много кода. Вы пытались отладить его, чтобы определить, где возникает ошибка? Вы дважды проверили, что все переменные определены с правильным типом?