I want to parse this response. Everything else is parsed - except Images. I receive it in a string but then I cannot convert it into a dictionary. This is my model.
struct PropertyList: Decodable {
let result: Property?
let success: Bool = false
struct Property: Decodable {
let name: String?
let description: String?
let propertyType: PropertyType
let latitude, longitude: String
let images: String?
let areaSize:Int?
let threeSixtyView: String?
let threeDModel: String?
enum CodingKeys: String, CodingKey {
case name
case propertyDescription = "description"
case propertyType, latitude, longitude
case threeDModel = "threeDModel"
case images = "images"
}
}
}
struct PropertyType: Codable {
let id: Int
let name, propertyTypeDescription: String
enum CodingKeys: String, CodingKey {
case id, name
case propertyTypeDescription = "description"
}
}
API Response :
"name": "Al Deyar",
"description": "Al Deyar Villa",
"propertyType": {
"id": 709415277471,
"name": "villa",
"description": "villa"
},
"latitude": "1",
"longitude": "2",
"viewOfWater": null,
"threeDModel": "https://viewer.archilogic.com/?sceneId=80d4b3bb-98de-4279-a867-633bf67c6e72&s=m2fss0p3slst",
"images": "[{\"id\": 1, \"image\":\"https://neigborhood-images.s3.amazonaws.com/property/1BEEA0B6-A2B1-4D5E-837B-9C2B00F46EE4_2048x2048.jpg\"},\n{\"id\": 2, \"image\":\"https://neigborhood-images.s3.amazonaws.com/property/984D2D29-2448-4B68-827F-EC912AB9AF14_2048x2048.jpg\"},\n{\"id\": 3, \"image\":\"https://neigborhood-images.s3.amazonaws.com/property/EBARZA-_0002_Layer_11_2048x2048.jpg\"},\n{\"id\": 4, \"image\":\"https://neigborhood-images.s3.amazonaws.com/property/EBARZA-_0002_Layer_10_ad2d92e2-3740-4d1d-8e9c-ed41cf89c3b2_2048x2048.jpg\"},\n{\"id\": 5, \"image\":\"https://neigborhood-images.s3.amazonaws.com/property/EBARZA-furniture_0001_Layer_21_2048x2048.jpg\"},\n{\"id\": 6, \"image\":\"https://neigborhood-images.s3.amazonaws.com/property/EBARZA-furniture_0044_Layer_5_2048x2048.jpg\"},\n{\"id\": 7, \"image\":\"https://neigborhood-images.s3.amazonaws.com/property/EBARZA-furniture_0042_Layer_3_2048x2048.jpg\"}]"
> Blockquote
images is a nested JSON string which has to be decoded separately.
A solution is to declare the value containing the nested JSON string as struct (ImageJSON) with a singleValueContainer and decode the string on second level.
I left out the properties which are not in the JSON
let json = """
{
"success" : true,
"result" : {
"name": "Al Deyar",
"description": "Al Deyar Villa",
"propertyType": {
"id": 709415277471,
"name": "villa",
"description": "villa"
},
"latitude": "1",
"longitude": "2",
"viewOfWater": null,
"threeDModel": "https://viewer.archilogic.com/?sceneId=80d4b3bb-98de-4279-a867-633bf67c6e72&s=m2fss0p3slst",
"images":"[{\\"id\\": 1, \\"image\\":\\"https://neigborhood-images.s3.amazonaws.com/property/1BEEA0B6-A2B1-4D5E-837B-9C2B00F46EE4_2048x2048.jpg\\"},{\\"id\\": 2,\\"image\\":\\"https://neigborhood-images.s3.amazonaws.com/property/984D2D29-2448-4B68-827F-EC912AB9AF14_2048x2048.jpg\\"},{\\"id\\": 3,\\"image\\":\\"https://neigborhood-images.s3.amazonaws.com/property/EBARZA-_0002_Layer_11_2048x2048.jpg\\"},{\\"id\\": 4,\\"image\\":\\"https://neigborhood-images.s3.amazonaws.com/property/EBARZA-_0002_Layer_10_ad2d92e2-3740-4d1d-8e9c-ed41cf89c3b2_2048x2048.jpg\\"},{\\"id\\": 5,\\"image\\":\\"https://neigborhood-images.s3.amazonaws.com/property/EBARZA-furniture_0001_Layer_21_2048x2048.jpg\\"},{\\"id\\": 6,\\"image\\":\\"https://neigborhood-images.s3.amazonaws.com/property/EBARZA-furniture_0044_Layer_5_2048x2048.jpg\\"},{\\"id\\": 7,\\"image\\":\\"https://neigborhood-images.s3.amazonaws.com/property/EBARZA-furniture_0042_Layer_3_2048x2048.jpg\\"}]"
}
}
"""
struct Response : Decodable {
let result: Property
let success: Bool
}
struct Property: Decodable {
let name: String
let description: String
let propertyType: PropertyType
let latitude, longitude: String
let images: ImageJSON
let threeDModel: URL
}
struct PropertyType: Codable {
let id: Int
let name, description: String
}
struct Image : Decodable {
let id : Int
let image : URL
}
struct ImageJSON : Decodable {
let images : [Image]
init(from decoder : Decoder) throws {
let container = try decoder.singleValueContainer()
let imageJSONString = try container.decode(String.self)
let imageJSONData = Data(imageJSONString.utf8)
images = try JSONDecoder().decode([Image].self, from: imageJSONData)
}
}
let data = Data(json.utf8)
do {
let decoder = JSONDecoder()
let response = try decoder.decode(Response.self, from: data)
let images = response.result.images.images
print(images)
} catch {
print(error)
}
Try the below code :
Update your json :
let json = """
{
"name": "Al Deyar",
"description": "Al Deyar Villa",
"propertyType": {
"id": 709415277471,
"name": "villa",
"description": "villa"
},
"latitude": "1",
"longitude": "2",
"viewOfWater": null,
"threeDModel":"https://viewer.archilogic.com/?sceneId=80d4b3bb-98de-4279-a867-633bf67c6e72&s=m2fss0p3slst",
"images": [
{"id": 1, "image": "https://neigborhood-images.s3.amazonaws.com/property/1BEEA0B6-A2B1-4D5E-837B-9C2B00F46EE4_2048x2048.jpg"},
{"id": 2, "image": "https://neigborhood-images.s3.amazonaws.com/property/984D2D29-2448-4B68-827F-EC912AB9AF14_2048x2048.jpg"},
{"id": 3, "image": "https://neigborhood-images.s3.amazonaws.com/property/EBARZA-_0002_Layer_11_2048x2048.jpg"},
{"id": 4, "image": "https://neigborhood-images.s3.amazonaws.com/property/EBARZA-_0002_Layer_10_ad2d92e2-3740-4d1d-8e9c-ed41cf89c3b2_2048x2048.jpg"},
{"id": 5, "image": "https://neigborhood-images.s3.amazonaws.com/property/EBARZA-furniture_0001_Layer_21_2048x2048.jpg"},
{"id": 6, "image": "https://neigborhood-images.s3.amazonaws.com/property/EBARZA-furniture_0044_Layer_5_2048x2048.jpg"},
{"id": 7, "image": "https://neigborhood-images.s3.amazonaws.com/property/EBARZA-furniture_0042_Layer_3_2048x2048.jpg"}
]
}
"""
Update your codable class :
struct Property : Codable {
let descriptionField : String?
let images : [Images]?
let latitude : String?
let longitude : String?
let name : String?
let propertyType : PropertyType?
let threeDModel : String?
let viewOfWater : String?
enum CodingKeys: String, CodingKey {
case descriptionField = "description"
case images = "images"
case latitude = "latitude"
case longitude = "longitude"
case name = "name"
case propertyType = "propertyType"
case threeDModel = "threeDModel"
case viewOfWater = "viewOfWater"
}
}
struct PropertyType : Codable {
let descriptionField : String?
let id : Int?
let name : String?
enum CodingKeys: String, CodingKey {
case descriptionField = "description"
case id = "id"
case name = "name"
}
}
struct Images : Codable {
let id : Int?
let image : String?
}
if let jsonData = json.data(using: .utf8) {
let decoder = JSONDecoder()
do {
let jsonModel = try decoder.decode(Property.self, from: jsonData)
print(jsonModel)
} catch {
print("Error = \(error)")
}
}
Create an image type as below,
struct PropertyImage: Decodable {
var id: Int
var image: String?
}
Now, get data from the images string and decode an array of property images as below,
if let data = property.images.data(using: .utf8) {
do {
let images = try JSONDecoder().decode([PropertyImage].self, from: data)
images.forEach { image in
print(image.id)
print(image.image)
}
} catch {
print(error)
}
}
Related
here my JSON is -
{
"status": "success",
"data": [
{
"_id": "15756323",
"name": "A",
"icons": "https://sdfgsuew34j.png",
"createdAt": "2021-03-18T13:06:44.054Z",
"updatedAt": "2021-03-18T13:06:44.054Z",
"__v": 0,
"id": "6053503drm476"
},
{
"_id": "45646054821",
"name": "S",
"icons": "https://dkj/djf.png",
"createdAt": "2021-03-19T10:51:07.066Z",
"updatedAt": "2021-03-19T10:51:07.066Z",
"__v": 0,
"id": "6054821b11kd6873"
}
]
}
I'm trying to print API data in collectionView
here's some code
var places: [Post]?
func apicall() {
let url = URL(string: "http://17.550.457.84/api/category/list")!
URLSession.shared.dataTask(with: url) { (data, response, error) in
if error == nil {
do {
self.places = try JSONDecoder().decode([Post].self, from: data! )
} catch {
print("Error during JSON serialization: \(error.localizedDescription)")
}
}
}.resume()
}
I get a message in the debugger -> Error during JSON serialization: The data couldn’t be read because it isn’t in the correct format.
i also try to change -> self.places = try JSONDecoder().decode([Post].self, from: data! )` to
self.places = try JSONDecoder().decode(Post.self, from: data! )
then I got the error -> Cannot assign the value of type 'Post' to type '[Post]?'
here my model class is
struct Post : Codable {
let _id : String?
let name : String?
let icons : String?
let createdAt : String?
let updatedAt : String?
let __v : Int?
let id : String?
enum CodingKeys: String, CodingKey {
case _id = "_id"
case name = "name"
case icons = "icons"
case createdAt = "createdAt"
case updatedAt = "updatedAt"
case __v = "__v"
case id = "id"
}
The error message basically says "Your model and coming data model(JSON) are not equal". You need to change your model like :
struct BaseModel : Codable{
var status : String?
var data : [Post]?
}
And when you try to deserialize it you need to make a instance of that BaseModel so
var baseModel: BaseModel?
var places: [Post]?
when response success
do {
let responseData = try JSONDecoder().decode(BaseModel.self, from: data! )
self.places = responseData.data!
} catch {
print("Error during JSON serialization: \(error.localizedDescription
}
I receive the following 2 responses from different APIs
{
"id": "jdu72bdj",
"userInfo": {
"name": "Sudhanshu",
"age": 28,
"country": "India"
}
}
and
{
"profileId": "jdu72bdj",
"profileDetails": {
"name": "Sudhanshu",
"age": 28,
"country": "India"
}
}
This is in context with iOS development using Swift language.
Basically the object structure is same but keys are different. I'm parsing these using Codable, but I cannot think of a way to parse using same struct. All I can think of is making 2 different structs like this -
public struct Container1: Codable {
public let id: String
public let userInfo: UserProfile?
}
and
public struct Container2: Codable {
public let profileId: String
public let profileDetails: UserProfile?
}
They both use common UserProfile struct.
public struct UserProfile: Codable {
public let name: String?
public let age: Int?
public let country: String?
}
Is there a way to use one common container struct for both responses which parse response from 2 different keys. I do not want Container1 and Container2 since they both have same structure.
Any suggestions ?
One solution is to use a custom key decoding strategy using an implementation of CodingKey found in Apple's documentation. The idea is to map the keys of both of the json messages to the properties of the struct Container that will be used for both messages.
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .custom({ keys in
let key = keys.last!.stringValue
switch key {
case "id", "profileId":
return AnyKey(stringValue: "id")!
case "userInfo", "profileDetails":
return AnyKey(stringValue: "details")!
default:
return keys.last!
}
})
where the custom implementation of CodingKey is
struct AnyKey: CodingKey {
var stringValue: String
var intValue: Int?
init?(stringValue: String) {
print(stringValue)
self.stringValue = stringValue
intValue = nil
}
init?(intValue: Int) {
self.stringValue = String(intValue)
self.intValue = intValue
}
}
and then decode both json messages the same way using the below struct
struct Container: Codable {
let id: String
let details: UserProfile
}
let result = try decoder.decode(Container.self, from: data)
You can use your own init from decoder
struct UniversalProfileContainer: Decodable {
struct UserProfile: Decodable {
var name: String
var age: Int
var country: String
}
enum CodingKeys: String, CodingKey {
case id = "id"
case profileId = "profileId"
case userInfo = "userInfo"
case profileDetails = "profileDetails"
}
let id: String
let profile: UserProfile
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
do {
id = try container.decode(String.self, forKey: .id)
} catch {
id = try container.decode(String.self, forKey: .profileId)
}
do {
profile = try container.decode(UserProfile.self, forKey: .userInfo)
} catch {
profile = try container.decode(UserProfile.self, forKey: .profileDetails)
}
}
}
let first = """
{
"id": "jdu72bdj",
"userInfo": {
"name": "Sudhanshu",
"age": 28,
"country": "India"
}
}
"""
let second = """
{
"profileId": "jdu72bdj",
"profileDetails": {
"name": "Sudhanshu",
"age": 28,
"country": "India"
}
}
"""
let response1 = try? JSONDecoder().decode(UniversalProfileContainer.self,
from: first.data(using: .utf8)!)
let response2 = try? JSONDecoder().decode(UniversalProfileContainer.self,
from: second.data(using: .utf8)!)
i have a local json string and i am trying to parse it but when i try to do so, i am constantly getting an error. I have also seen this error in nested dictionary but couldnt find an error.
Below is the json string
let jsonNestedString = "{\"meta\":{\"page\":1,\"total_pages\":4,\"per_page\":10,\"total_records\" : 38}, \"reweries\":[\"id\":1234,\"name\":\"saintArnold\"},{\"id\":52892,\"name\":\"buffalo bayou\"]}"
i am doing this process via Codable and below is the struct i have created for the same
struct PagedBreweries:Codable{
struct Meta:Codable{
let page : Int
let total_pages:Int
let per_page:Int
let total_records: Int
enum CodingKeys: String, CodingKey{
case page
case total_pages
case per_page
case total_records
}
}
struct Brewery :Codable{
let id:Int
let name:String
}
let meta:Meta
let breweries :[Brewery]
}
then this data is parsed to a function as below
func jsonNested(){
let jsonData = jsonNestedString.data(using: .utf8)
let decoder = JSONDecoder()
let data = try! decoder.decode(PagedBreweries.Meta.self, from: jsonData!)
print(data)
}
and when i try to build, the error i get is present in try! decoder.decode
command
and the error is
Thread 1: Fatal error: 'try!' expression unexpectedly raised an error: Swift.DecodingError.keyNotFound(CodingKeys(stringValue: "page", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"page\", intValue: nil) (\"page\").", underlyingError: nil))
Could any one provide a solution?
Thanks in advance
Correct json
{
"meta": {
"page": 1,
"total_pages": 4,
"per_page": 10,
"total_records": 38
},
"reweries": [{
"id": 1234,
"name": "saintArnold"
},
{
"id": 52892,
"name": "buffalo bayou"
}
]
}
struct Root: Codable {
let meta: Meta
let reweries: [Rewery]
}
struct Meta: Codable {
let page, totalPages, perPage, totalRecords: Int
enum CodingKeys: String, CodingKey { // snake case may be used
case age = "page"
case totalPages = "total_pages"
case perPage = "per_page"
case totalRecords = "total_records"
}
}
struct Rewery: Codable {
let id: Int
let name: String
}
let jsonNestedString = """
{\"meta\":{\"page\":1,\"total_pages\":4,\"per_page\":10,\"total_records\":38}, \"reweries\":[{\"id\":1234,\"name\":\"saintArnold\"},{\"id\":52892,\"name\":\"buffalo bayou\"}]}
"""
// or
let jsonNestedString = """
{
"meta": {
"page": 1,
"total_pages": 4,
"per_page": 10,
"total_records": 38
},
"reweries": [{
"id": 1234,
"name": "saintArnold"
},
{
"id": 52892,
"name": "buffalo bayou"
}
]
}
"""
do {
let jsonData = jsonNestedString.data(using: .utf8)
let decoder = JSONDecoder()
let data = try decoder.decode(Root.self, from: jsonData!)
print(data)
} catch {
print(error)
}
The JSON is corrupt and you are decoding the wrong root object.
This is the correct JSON being decoded with your structs and conforming to the Swift naming convention
let jsonNestedString = """
{"meta":{"page":1,"total_pages":4,"per_page":10,"total_records" : 38}, "breweries":[{"id":1234,"name":"saintArnold"},{"id":52892,"name":"buffalo bayou"}]}
"""
struct PagedBreweries : Codable {
struct Meta : Codable {
let page : Int
let totalPages:Int
let perPage:Int
let totalRecords: Int
}
struct Brewery : Codable {
let id:Int
let name:String
}
let meta:Meta
let breweries :[Brewery]
}
func jsonNested(){
let jsonData = Data(jsonNestedString.utf8)
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let data = try! decoder.decode(PagedBreweries.self, from: jsonData)
print(data)
}
jsonNested()
// Printed result:
// PagedBreweries(meta: __lldb_expr_1.PagedBreweries.Meta(page: 1, totalPages: 4, perPage: 10, totalRecords: 38), breweries: [__lldb_expr_1.PagedBreweries.Brewery(id: 1234, name: "saintArnold"), __lldb_expr_1.PagedBreweries.Brewery(id: 52892, name: "buffalo bayou")])
This is my JSON response:
[
[
{
"id": 22,
"request_id": "rqst5c12fc9e856ae1.06631647",
"business_name": "Code Viable",
"business_email": "code#viable.com",
"title": "Apache Load/Ubuntu",
}
],
[
{
"id": 24,
"request_id": "rqst5c130cae6f7609.41056231",
"business_name": "Code Viable",
"business_email": "code#viable.com",
"title": "Load",
}
]
]
This JSON structure got an array inside of an array, the object of the inner array is what I am trying to parse. Here is the my mapper:
struct JobResponseDataObject: Mappable {
init?(map: Map) {
}
var id: Int?
var requestId: String?
var businessName: String?
var businessEmail: String?
mutating func mapping(map: Map) {
id <- map["id"]
requestId <- map["request_id"]
businessName <- map["business_name"]
businessEmail <- map["business_email"]
}
}
I have tried create another mapper struct to hold the array of objects [JobResponseDataObject] and use Alamofire's responseArray with it, but it didn't work. I have also tried prefixing my json id with 0. but that didn't work too. Please help
Thank
So here's the deal...Codable is a pretty cool protocol from Apple to handle parsing JSON responses from APIs. What you're getting back is an array of arrays, so your stuff's gonna be look like this:
[[ResponseObject]]
So anyway, you'd make a struct of your object, like so:
struct ResponseObject: Codable {
let id: Int?
let requestId: String?
let businessName: String?
let businessEmail: String?
let title: String?
}
You'll note I changed the key name a bit (instead of request_id, I used requestId). The reason is JSONDecoder has a property called keyDecodingStrategy which presents an enum of canned decoding strategies you can select from. You'd do convertFromSnakeCase.
Here's code you can dump into a playground to tinker with. Basically, declare your struct, match it up to whatever the keys are in your JSON, declare a decoder, feed it a decoding strategy, and then decode it.
Here's how you could do an Alamofire call:
private let backgroundThread = DispatchQueue(label: "background",
qos: .userInitiated,
attributes: .concurrent,
autoreleaseFrequency: .inherit,
target: nil)
Alamofire.request(url).responseJSON(queue: backgroundThread) { (response) in
guard response.result.error == nil else {
print("💥KABOOM!💥")
return
}
if let data = response.data {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
do {
let parsedResponse = try decoder.decode([[ResponseObject]].self, from: data)
print(parsedResponse)
} catch {
print(error.localizedDescription)
}
}
}
Here's code you can chuck in a playground.
import UIKit
let json = """
[
[
{
"id": 22,
"request_id": "rqst5c12fc9e856ae1.06631647",
"business_name": "Code Viable",
"business_email": "code#viable.com",
"title": "Apache Load/Ubuntu",
}
],
[
{
"id": 24,
"request_id": "rqst5c130cae6f7609.41056231",
"business_name": "Code Viable",
"business_email": "code#viable.com",
"title": "Load",
}
]
]
"""
struct ResponseObject: Codable {
let id: Int?
let requestId: String?
let businessName: String?
let businessEmail: String?
let title: String?
}
if let data = json.data(using: .utf8) {
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
do {
let parsedResponse = try decoder.decode([[ResponseObject]].self, from: data)
print(parsedResponse)
} catch {
print(error.localizedDescription)
}
}
You should use this JobResponseDataObject struct as [[JobResponseDataObject]] instead of [JobResponseDataObject] - where you are making a property using this struct in your parent struct or class.
You can use Codable here for mapping the JSON response, The JobResponseDataObject struct should look like,
struct JobResponseDataObject: Codable {
var id: Int?
var requestId: String?
var businessName: String?
var businessEmail: String?
var title: String?
private enum CodingKeys: String, CodingKey {
case id = "id"
case requestId = "request_id"
case businessName = "business_name"
case businessEmail = "business_email"
case title = "title"
}
}
let json = JSON(responseJSON: jsonData)
do {
if let value = try? json.rawData(){
let response = try! JSONDecoder().decode([[JobResponseDataObject]].self, from: value)
}
} catch {
print(error.localizedDescription)
}
let APIUrl = NSURL(string:"https://api.openweathermap.org/data/2.5/weather?lat=(currentLocation.coordinate.latitude)&lon=(currentLocation.coordinate.longitude)&appid=e7b2054dc37b1f464d912c00dd309595&units=Metric%22")
let request = URLRequest(url:APIUrl! as URL)
let dataTask = URLSession.shared.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
if (error != nil) {
print(error ?? "Error is empty.")
} else {
let httpResponse = response as? HTTPURLResponse
print(httpResponse ?? "HTTP response is empty.")
}
guard let responseData = data else {
print("Error: did not receive data")
return
}
do {
let weatherData = try JSONDecoder().decode(MyWeather.self, from: responseData)
let ggtemp = weatherData.main?.temp
print(ggtemp!, "THIS IS THE TEMP")
DispatchQueue.main.async {
self.tempDisplay.text = String(format: "%.1f", ggtemp!)
}
} catch {
print("error parsing response from POST on /todos")
return
}
})
dataTask.resume()
}
I want to get the temperature of my current Location.
Here is what I get when app runs:
<NSHTTPURLResponse: 0x28322fbe0> { URL: https://api.openweathermap.org/data/2.5/weather?lat=(currentLocation.coordinate.latitude)&lon=(currentLocation.coordinate.longitude)&appid=e7b2054dc37b1f464d912c00dd309595&units=Metric%22 } { Status Code: 400, Headers {
"Access-Control-Allow-Credentials" = (
true
);
"Access-Control-Allow-Methods" = (
"GET, POST"
);
"Access-Control-Allow-Origin" = (
"*"
);
Connection = (
"keep-alive"
);
"Content-Length" = (
78
);
"Content-Type" = (
"application/json; charset=utf-8"
);
Date = (
"Sun, 21 Oct 2018 09:57:38 GMT"
);
Server = (
openresty
);
"X-Cache-Key" = (
"/data/2.5/weather?lat=&lon=&units=Metric%22"
);
} }
error parsing response from POST on /todos
Any ideas on how to get the temp from this API?
Here is my struct code:
struct Coordinate : Decodable {
let lat, lon : Double?
}
struct Weather : Decodable {
var id : Int?
var main, myDescription, icon : String?
enum CodingKeys : String, CodingKey {
case id = "id"
case main = "main"
case icon = "icon"
case myDescription = "description"
}
}
struct Sys : Decodable {
let type, id : Int?
let sunrise, sunset : Date?
let message : Double?
let country : String?
}
struct Main : Decodable {
let temp : Double?
}
struct MyWeather : Decodable {
let coord : Coordinate?
let cod, visibility, id : Int?
let name : String?
let base : String?
let weather : [Weather]?
let sys : Sys?
let main : Main?
let dt : Date?
}
I check your api in postman get this response
{
"coord": {
"lon": 90.36,
"lat": 23.79
},
"weather": [
{
"id": 721,
"main": "Haze",
"description": "haze",
"icon": "50d"
}
],
"base": "stations",
"main": {
"temp": 304.15,
"pressure": 1013,
"humidity": 62,
"temp_min": 304.15,
"temp_max": 304.15
},
"visibility": 3000,
"wind": {
"speed": 4.1,
"deg": 330
},
"clouds": {
"all": 20
},
"dt": 1540182600,
"sys": {
"type": 1,
"id": 7879,
"message": 0.0056,
"country": "BD",
"sunrise": 1540166342,
"sunset": 1540207601
},
"id": 1337178,
"name": "Dhaka District",
"cod": 200
}
this is your full API response model class used this code
struct MyWeather : Decodable {
let coord : Coordinate?
let weather : [Weather]?
let base : String?
let main : Main?
let visibility: Int?
let wind : Wind?
let clouds : Clouds?
let dt : Date?
let sys : Sys?
let id : Int?
let name : String?
let cod : Int?
}
struct Coordinate : Decodable {
let lat : Double?
let lon : Double?
}
struct Weather : Decodable {
var id : Int?
var main, myDescription, icon : String?
enum CodingKeys : String, CodingKey {
case id = "id"
case main = "main"
case icon = "icon"
case myDescription = "description"
}
}
struct Main : Decodable {
let temp : Double?
let pressure : Int?
let humidity : Int?
let temp_min : Double?
let temp_max : Double?
}
struct Wind : Decodable {
let speed : Double?
let deg : Int?
}
struct Clouds: Decodable {
let all : Int?
}
struct Sys : Decodable {
let type : Int?
let id : Int?
let message : Double?
let country : String?
let sunrise : Date?
let sunset : Date?
}
Your code is parsing the data. However, I noticed at the end of your URL units=Metric%22 which should just be units=Metric. Also, your lat and lon will be incorrect. lat=(currentLocation.coordinate.latitude) should be lat=\(currentLocation.coordinate.latitude) and same for lon.