I am new to Codable in Swift, and am trying to get some data from an API (https://sportspagefeeds.com/documentation). I don't need to get all of the data from the API, just the field's specified in the model. I am getting this error when trying to run my code: typeMismatch(Swift.Array<Any>, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Array<Any> but found a dictionary instead.", underlyingError: nil))
Weirdly enough when I put the API response in a string then encode it I can successfully decode it with the same exact code. Anyone have any insight here? I am getting a 200
code from the response
code:
let request = NSMutableURLRequest(url: NSURL(string: "https://sportspage-feeds.p.rapidapi.com/games?league=NBA")! as URL,
cachePolicy: .useProtocolCachePolicy,
timeoutInterval: 10.0)
request.httpMethod = "GET"
request.allHTTPHeaderFields = headers
let session = URLSession.shared
session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
if let data = data {
do {
let dec = JSONDecoder()
dec.keyDecodingStrategy = .convertFromSnakeCase
let games = try dec.decode([Game].self, from: data)
print(games)
} catch {
print(error)
}
}
}).resume()
API return structure (from the link):
[
{
"gameId":"tv7mnr2-g7c4fe5-p95kxge-ptyhr72" ,
"details":{
"league":"NFL" ,
"season":2018 ,
"seasonType":"regular" ,
"conferenceGame":true ,
"divisionGame":true
} ,
"schedule":{
"date":"2018-12-30T18:00:00.000Z" ,
"tbaTime":false
} ,
"teams":{
"away":{
"team":"Miami Dolphins" ,
"location":"Miami" ,
"mascot":"Dolphins" ,
"abbreviation":"MIA" ,
"conference":"AFC" ,
"division":"East"
} ,
"home":{
"team":"Buffalo Bills" ,
"location":"Buffalo" ,
"mascot":"Bills" ,
"abbreviation":"BUF" ,
"conference":"AFC" ,
"division":"East"
}
} ,
"venue":{
"name":"New Era Field" ,
"city":"Orchard Park" ,
"state":"NY" ,
"neutralSite":false
} ,
"scoreboard":{
"score":{
"away":17 ,
"home":42 ,
"awayPeriods": [0 ,14 ,3 ,0] ,
"homePeriods": [14 ,0 ,14 ,14]
} ,
"currentPeriod":4 ,
"periodTimeRemaining":"0:00"
} ,
[ etc...... ]
]
Here are my models:
public struct Game: Codable {
public var gameId: String?
public var details: Details?
public var teams: Teams?
public var scoreboard: Scoreboard?
}
public struct Details: Codable {
public var league: String?
}
public struct Teams: Codable {
public var home: Team?
public var away: Team?
}
public struct Team: Codable {
public var team: String?
public var abbreviation: String?
}
public struct Scoreboard: Codable {
public var score: Score?
public var currentPeriod: Int?
public var periodTimeRemaining: String?
}
public struct Score: Codable {
public var away: Int?
public var home: Int?
}
let see the response from api:
"status": 200,
"time": "2021-03-26T01:42:14.010Z",
"games": 5,
"skip": 0,
"results": [....]
The response is Dictionary, but you encode it to Array of [Game] the why you receive this error. You need create more model like this
public struct GameResponse: Codable {
var status: Int
var time: String
var games: Int
var skip: Int
var results: [Game]
}
And decode reponse to GameResponseModel:
let games = try dec.decode(GameResponse.self, from: data)
And change your game id to Int, because it Int not String
public struct Game: Codable {
public var gameId: Int?
public var details: Details?
public var teams: Teams?
public var scoreboard: Scoreboard?
}