Reputation: 77
I can not pars data from fixtures array, every time I get a mistake
error in console log:
downloaded
Error info: typeMismatch(Swift.String, Swift.DecodingError.Context(codingPath: [LiveZscores.EventsFull.(CodingKeys in _B768B663C3B4834FEE8438F5C59CA80A).fixtures, Foundation.(_JSONKey in _12768CA107A31EF2DCE034FD75B541C9)(stringValue: "Index 0", intValue: Optional(0)), LiveZscores.EventsData.(CodingKeys in _B768B663C3B4834FEE8438F5C59CA80A).result], debugDescription: "Expected to decode String but found a dictionary instead.", underlyingError: nil))
My code:
ViewController.swift
final let url = URL(string: "http://api.football-data.org/v1/fixtures")
override func viewDidLoad() {
super.viewDidLoad()
downloadJson()
}
func downloadJson() {
guard let downloadURL = url else { return }
URLSession.shared.dataTask(with: downloadURL) { (data, urlResponse, error) in
guard let data = data, error == nil, urlResponse != nil else {
print ("something")
return
}
print ("downloaded")
do {
let decoder = JSONDecoder()
let events = try decoder.decode(EventsFull.self, from: data)
print (events.fixtures)
}catch {
print("Error info: \(error)")
}
}.resume()
}
Events.swift
class EventsFull: Codable {
let fixtures: [EventsData]
init(fixtures: [EventsData]) {
self.fixtures = fixtures
}
}
class EventsData: Codable {
let date: String
let status: String
let matchday: Int
let homeTeamName: String
let awayTeamName: String
let result: String
let odds: Double
init(date: String, status: String, matchday: Int, homeTeamName: String, awayTeamName: String, result: String, odds: Double) {
self.date = date
self.status = status
self.matchday = matchday
self.homeTeamName = homeTeamName
self.awayTeamName = awayTeamName
self.result = result
self.odds = odds
}
}
Upvotes: 2
Views: 8875
Reputation: 285230
Please learn to read error messages, especially Codable
messages are very easy to read.
This is the message a bit more structured
typeMismatch(Swift.String,
Swift.DecodingError.Context(codingPath: [LiveZscores.EventsFull.(CodingKeys in _B768B663C3B4834FEE8438F5C59CA80A).fixtures, Foundation.(_JSONKey in _12768CA107A31EF2DCE034FD75B541C9)(stringValue: "Index 0", intValue: Optional(0)),
LiveZscores.EventsData.(CodingKeys in _B768B663C3B4834FEE8438F5C59CA80A).result], debugDescription: "Expected to decode String but found a dictionary instead.", underlyingError: nil))
Swift.String
is the expected type in the struct / class
The most significant codingPath
information is
codingPath: [LiveZscores.EventsFull.fixtures,
LiveZscores.EventsData.result], debugDescription: "Expected to decode String but found a dictionary instead.", underlyingError: nil))
The error occurred in the key result
in the struct EventsData
which is in the struct EventsFull
for key fixtures
and the message tells you clearly what's wrong
Take a look at the JSON: The value for key result
is a dictionary which can be represented by another struct.
Normally you don't need a class inherited from NSObject
to decode JSON, a struct is sufficient and you don't need an initializer, the Codable
protocol provides the initializer.
All keys which can be null
must be declared as optional, both keys in Result
and the key odds
in EventsData
can be null
.
struct EventsFull: Decodable {
let fixtures: [EventsData]
}
struct EventsData: Decodable {
let date: String
let status: String
let matchday: Int
let homeTeamName: String
let awayTeamName: String
let result: Result
let odds: Double?
}
struct Result : Decodable {
let goalsHomeTeam : Int?
let goalsAwayTeam : Int?
}
Upvotes: 3