Reputation: 49
I am trying to write a function in swift that gets data from an URL JSON, and allocate it to variables in swift.
This is the function:
func getBikeData(){
guard let url = URL(string: "https://api.citybik.es//v2/networks/baksi-bisim") else {return}
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
guard let dataResponse = data,
error == nil else {
print(error?.localizedDescription ?? "Response Error")
return }
do{
//here dataResponse received from a network request
let jsonResponse = try JSONSerialization.jsonObject(with:
dataResponse, options: [])
print(jsonResponse) //Response result
do {
//here dataResponse received from a network request
let decoder = JSONDecoder()
//Decode JSON Response Data
let model = try decoder.decode(Station.self,
from: dataResponse)
print(model.freeBikes) //Output - 1221
} catch let parsingError {
print("Error", parsingError)
}
} catch let parsingError {
print("Error", parsingError)
}
}
task.resume()
}
This is the struct's that I added, with the data I need:
// MARK: - Station
struct Station: Codable {
let emptySlots: Int
let extra: Extra
let freeBikes: Int
let id: String
let latitude, longitude: Double
let name, timestamp: String
enum CodingKeys: String, CodingKey {
case emptySlots
case extra
case freeBikes
case id, latitude, longitude, name, timestamp
}
}
// MARK: - Extra
struct Extra: Codable {
let slots: Int
let status: Status
let uid: String
}
enum Status: String, Codable {
case active = "Active"
}
This is the error I have been receiving:
Error keyNotFound(CodingKeys(stringValue: "emptySlots", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"emptySlots\", intValue: nil) (\"emptySlots\").", underlyingError: nil))
This is the first time I was working with a JSON file, and maybe I am missing something very simple. Please help.
Upvotes: 2
Views: 661
Reputation: 1414
Error keyNotFound(CodingKeys(stringValue: "emptySlots", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"emptySlots\", intValue: nil) (\"emptySlots\").", underlyingError: nil))
The above error will occur if you are trying to decode a JSON object that doesn't have that key and the key is not marked as an optional.
You can either fix the server-end so emptySlots is returned or mark emptySlots as an optional in your struct:
struct Station: Codable {
let emptySlots: Int?
Upvotes: 1
Reputation: 987
Here is how to decode all the json data into a swift struct:
import Foundation
struct Stations: Codable {
let company: [String]
let href: String
let id: String
let location: LocationJson
let name: String
let stations: [Station]
}
struct Station: Codable {
let empty_slots: Int
let extra: Extra
let free_bikes: Int
let id: String
let latitude: Double
let longitude: Double
let name: String
let timestamp: String
}
struct ResponseJSON: Codable {
let network: Stations
}
struct LocationJson: Codable {
let city: String
let country: String
let latitude: Double
let longitude: Double
}
struct Extra: Codable {
let slots: Int
let status: String
let uid: String
}
func getBikeData(){
guard let url = URL(
string: "https://api.citybik.es//v2/networks/baksi-bisim"
) else { return }
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
guard let dataResponse = data, error == nil else {
print(error?.localizedDescription ?? "Response Error")
return
}
do {
//here dataResponse received from a network request
let jsonResponse = try JSONSerialization.jsonObject(with:
dataResponse, options: [])
print(jsonResponse) //Response result
do {
//here dataResponse received from a network request
let decoder = JSONDecoder()
//Decode JSON Response Data
let model = try decoder.decode(
ResponseJSON.self, from: dataResponse
)
print(model) //Output - 1221
} catch let parsingError {
print("Error", parsingError)
}
} catch let parsingError {
print("Error", parsingError)
}
}
task.resume()
}
getBikeData()
Upvotes: 1