应为数组,但在 Swift 中找到了字典
Expected Array but found Dictionary in Swift
我是 Swift 的 Codable 新手,我正在尝试从 API (https://sportspagefeeds.com/documentation) 获取一些数据。我不需要从 API 中获取所有数据,只需在模型中指定字段即可。我在尝试 运行 我的代码时遇到此错误:typeMismatch(Swift.Array<Any>, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Array<Any> but found a dictionary instead.", underlyingError: nil))
奇怪的是,当我将 API 响应放入字符串中然后对其进行编码时,我可以使用完全相同的代码成功解码它。有人在这里有任何见解吗?我从响应
中得到一个 200
代码
代码:
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结构(来自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...... ]
]
这是我的模型:
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?
}
看看api的回复:
"status": 200,
"time": "2021-03-26T01:42:14.010Z",
"games": 5,
"skip": 0,
"results": [....]
响应是字典,但您将其编码为 [游戏] 数组,这就是您收到此错误的原因。您需要创建更多这样的模型
public struct GameResponse: Codable {
var status: Int
var time: String
var games: Int
var skip: Int
var results: [Game]
}
并解码对 GameResponseModel 的响应:
let games = try dec.decode(GameResponse.self, from: data)
并且将你的游戏 id 更改为 Int,因为它是 Int 而不是 String
public struct Game: Codable {
public var gameId: Int?
public var details: Details?
public var teams: Teams?
public var scoreboard: Scoreboard?
}
我是 Swift 的 Codable 新手,我正在尝试从 API (https://sportspagefeeds.com/documentation) 获取一些数据。我不需要从 API 中获取所有数据,只需在模型中指定字段即可。我在尝试 运行 我的代码时遇到此错误:typeMismatch(Swift.Array<Any>, Swift.DecodingError.Context(codingPath: [], debugDescription: "Expected to decode Array<Any> but found a dictionary instead.", underlyingError: nil))
奇怪的是,当我将 API 响应放入字符串中然后对其进行编码时,我可以使用完全相同的代码成功解码它。有人在这里有任何见解吗?我从响应
中得到一个200
代码
代码:
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结构(来自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...... ]
]
这是我的模型:
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?
}
看看api的回复:
"status": 200,
"time": "2021-03-26T01:42:14.010Z",
"games": 5,
"skip": 0,
"results": [....]
响应是字典,但您将其编码为 [游戏] 数组,这就是您收到此错误的原因。您需要创建更多这样的模型
public struct GameResponse: Codable {
var status: Int
var time: String
var games: Int
var skip: Int
var results: [Game]
}
并解码对 GameResponseModel 的响应:
let games = try dec.decode(GameResponse.self, from: data)
并且将你的游戏 id 更改为 Int,因为它是 Int 而不是 String
public struct Game: Codable {
public var gameId: Int?
public var details: Details?
public var teams: Teams?
public var scoreboard: Scoreboard?
}