无法解析来自 F1 url 的 JSON 数据
Not able to parse the JSON data from F1 url
我正在尝试使用以下 url http://ergast.com/api/f1/1950/driverstandings.json
访问 JSON 数据
现在我可以使用以下函数访问数据了。
换句话说,我可以在控制台中显示数据。我遇到的问题是解析 JSON 数据。
我正在使用 Swifty JSON 来解析数据,但出于某种原因我无法显示来自 API 的数据。
下面的函数更新故事板上的 UILabel。
如有任何帮助,我们将不胜感激。以下是我要解决的问题的完整代码。我想补充一点,url 将在另一个视图上出现 UIPickerView。
导入 UIKit
进口 Alamofire
导入 SwiftyJSON
class StandingViewController: UIViewController {
@IBOutlet weak var yearLabel: UILabel!
@IBOutlet weak var firstLabel: UILabel!
@IBOutlet weak var secondLabel: UILabel!
@IBOutlet weak var thirdLabel: UILabel!
@IBOutlet weak var fouthLabel: UILabel!
@IBOutlet weak var fifthLabel: UILabel!
var standing = ""
let standingDataModel = WeatherDataModel()
var currentUrl = ""
let SEASON_URL = "https://ergast.com/api/f1"
//let format = ".json"
override func viewDidLoad() {
super.viewDidLoad()
yearLabel.text = standing
userEnteredNewYear(standing: standing)
// Do any additional setup after loading the view.
}
//MARK: - Networking
/***************************************************************/
//Write the getStandingData method here:
func getStandingData (url: String) {
Alamofire.request(url, method: .get).responseJSON {
response in
if response.result.isSuccess {
print("Success we got the data!")
let standingJSON : JSON = JSON(response.result.value!)
print(standingJSON)
self.updateStandingData(json: standingJSON)
} else {
print("Error \(String(describing: response.result.error))")
self.yearLabel.text = "Connection Issues"
}
}
}
//Mark: JSON Parsing
func updateStandingData(json: JSON) {
if case standingDataModel.season = json["MRData"]["StandingsTable"]["season"].intValue {
standingDataModel.firstDriver = json["DriverStandings"][0]["Driver"]["driverId"].stringValue
updateUIWithStandingData()
} else {
yearLabel.text = "No data available"
}
}
//Mark user entered data.
func userEnteredNewYear(standing: String) {
currentUrl = SEASON_URL + "/" + String(standing) + "/driverstandings.json"
getStandingData(url: currentUrl)
}
func updateUIWithStandingData() {
yearLabel.text = "\(standingDataModel.season)"
firstLabel.text = standingDataModel.firstDriver
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
我建议放弃 SwiftyJSON。改为创建真实模型对象并使用 Swift 的内置 Codable:
struct F1Data: Codable {
let mrData: MRData
enum CodingKeys: String, CodingKey {
case mrData = "MRData"
}
}
struct MRData: Codable {
let xmlns: String
let series: String
let url: String
let limit, offset, total: String
let standingsTable: StandingsTable
enum CodingKeys: String, CodingKey {
case xmlns, series, url, limit, offset, total
case standingsTable = "StandingsTable"
}
}
struct StandingsTable: Codable {
let season: String
let standingsLists: [StandingsList]
enum CodingKeys: String, CodingKey {
case season
case standingsLists = "StandingsLists"
}
}
struct StandingsList: Codable {
let season, round: String
let driverStandings: [DriverStanding]
enum CodingKeys: String, CodingKey {
case season, round
case driverStandings = "DriverStandings"
}
}
struct DriverStanding: Codable {
let position, positionText, points, wins: String
let driver: Driver
let constructors: [Constructor]
enum CodingKeys: String, CodingKey {
case position, positionText, points, wins
case driver = "Driver"
case constructors = "Constructors"
}
}
struct Constructor: Codable {
let constructorId: String
let url: String
let name: String
let nationality: String
}
struct Driver: Codable {
let driverId: String
let url: String
let givenName, familyName, dateOfBirth, nationality: String
}
do {
let f1Data = try JSONDecoder().decode(F1Data.self, from: jsonData)
let season = f1Data.mrData.standingsTable.season
let firstDriver = f1Data.mrData.standingsTable.standingsLists[0].driverStandings[0].driver.driverId
} catch {
print(error)
}
我正在尝试使用以下 url http://ergast.com/api/f1/1950/driverstandings.json
访问 JSON 数据现在我可以使用以下函数访问数据了。
换句话说,我可以在控制台中显示数据。我遇到的问题是解析 JSON 数据。
我正在使用 Swifty JSON 来解析数据,但出于某种原因我无法显示来自 API 的数据。 下面的函数更新故事板上的 UILabel。
如有任何帮助,我们将不胜感激。以下是我要解决的问题的完整代码。我想补充一点,url 将在另一个视图上出现 UIPickerView。 导入 UIKit 进口 Alamofire 导入 SwiftyJSON
class StandingViewController: UIViewController {
@IBOutlet weak var yearLabel: UILabel!
@IBOutlet weak var firstLabel: UILabel!
@IBOutlet weak var secondLabel: UILabel!
@IBOutlet weak var thirdLabel: UILabel!
@IBOutlet weak var fouthLabel: UILabel!
@IBOutlet weak var fifthLabel: UILabel!
var standing = ""
let standingDataModel = WeatherDataModel()
var currentUrl = ""
let SEASON_URL = "https://ergast.com/api/f1"
//let format = ".json"
override func viewDidLoad() {
super.viewDidLoad()
yearLabel.text = standing
userEnteredNewYear(standing: standing)
// Do any additional setup after loading the view.
}
//MARK: - Networking
/***************************************************************/
//Write the getStandingData method here:
func getStandingData (url: String) {
Alamofire.request(url, method: .get).responseJSON {
response in
if response.result.isSuccess {
print("Success we got the data!")
let standingJSON : JSON = JSON(response.result.value!)
print(standingJSON)
self.updateStandingData(json: standingJSON)
} else {
print("Error \(String(describing: response.result.error))")
self.yearLabel.text = "Connection Issues"
}
}
}
//Mark: JSON Parsing
func updateStandingData(json: JSON) {
if case standingDataModel.season = json["MRData"]["StandingsTable"]["season"].intValue {
standingDataModel.firstDriver = json["DriverStandings"][0]["Driver"]["driverId"].stringValue
updateUIWithStandingData()
} else {
yearLabel.text = "No data available"
}
}
//Mark user entered data.
func userEnteredNewYear(standing: String) {
currentUrl = SEASON_URL + "/" + String(standing) + "/driverstandings.json"
getStandingData(url: currentUrl)
}
func updateUIWithStandingData() {
yearLabel.text = "\(standingDataModel.season)"
firstLabel.text = standingDataModel.firstDriver
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the new view controller using segue.destination.
// Pass the selected object to the new view controller.
}
*/
}
我建议放弃 SwiftyJSON。改为创建真实模型对象并使用 Swift 的内置 Codable:
struct F1Data: Codable {
let mrData: MRData
enum CodingKeys: String, CodingKey {
case mrData = "MRData"
}
}
struct MRData: Codable {
let xmlns: String
let series: String
let url: String
let limit, offset, total: String
let standingsTable: StandingsTable
enum CodingKeys: String, CodingKey {
case xmlns, series, url, limit, offset, total
case standingsTable = "StandingsTable"
}
}
struct StandingsTable: Codable {
let season: String
let standingsLists: [StandingsList]
enum CodingKeys: String, CodingKey {
case season
case standingsLists = "StandingsLists"
}
}
struct StandingsList: Codable {
let season, round: String
let driverStandings: [DriverStanding]
enum CodingKeys: String, CodingKey {
case season, round
case driverStandings = "DriverStandings"
}
}
struct DriverStanding: Codable {
let position, positionText, points, wins: String
let driver: Driver
let constructors: [Constructor]
enum CodingKeys: String, CodingKey {
case position, positionText, points, wins
case driver = "Driver"
case constructors = "Constructors"
}
}
struct Constructor: Codable {
let constructorId: String
let url: String
let name: String
let nationality: String
}
struct Driver: Codable {
let driverId: String
let url: String
let givenName, familyName, dateOfBirth, nationality: String
}
do {
let f1Data = try JSONDecoder().decode(F1Data.self, from: jsonData)
let season = f1Data.mrData.standingsTable.season
let firstDriver = f1Data.mrData.standingsTable.standingsLists[0].driverStandings[0].driver.driverId
} catch {
print(error)
}