简体   繁体   中英

Swift 5: JSON object array to swift structure

i have no experience with creating apps in swift but please bear with us. I would like to get data from public API in JSON format and create struct in swift, so i've found some tutorials but i' am facing issues.

I'm pretty sure that api returns json values, i've tested it via

let dataAsString = String(data: data, encoding: .utf8)

and i've got correct response.

But when i try to make objects from this response

let stations = try JSONDecoder().decode([Station].self, from: data)
                print(stations) // returns nil

It prints this error:

//Error:  typeMismatch(Swift.Double, Swift.DecodingError.Context(codingPath: [_JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "gegrLat", intValue: nil)], debugDescription: "Expected to decode Double but found a string/data instead.", underlyingError: nil))

All of my code with data structures:

import UIKit

struct Commune: Codable{
    var communeName: String
    var districtName: String
    var proviceName: String
}

struct City: Codable{
    var id: Int
    var name: String
    var commune: Commune
}

struct Station: Codable {
    var id: Int
    var stationName: String
    var gegrLat: Double
    var gegrLon: Double
    var city: City
    var addressStreet: String?
}

class SearchViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let searchController = UISearchController(searchResultsController: nil)
        self.navigationItem.searchController = searchController

        let jsonUrlString = "http://api.gios.gov.pl/pjp-api/rest/station/findAll"
        guard let url = URL(string: jsonUrlString) else { return }

        URLSession.shared.dataTask(with: url){ (data, response, error) in
            guard let data = data else { return }
            //let dataAsString = String(data: data, encoding: .utf8)
            //print(dataAsString) //working fine, returns string with data

            //let json = try? JSONSerialization.jsonObject( with: data, options: .mutableContainers)
            //print(json) //also working fine, returns json

            do{
                let stations = try JSONDecoder().decode([Station].self, from: data)
                print(stations) // returns nil
            } catch let jsonErr {
                print("Error: ", jsonErr)
                //Error:  typeMismatch(Swift.Double, Swift.DecodingError.Context(codingPath: [_JSONKey(stringValue: "Index 0", intValue: 0), CodingKeys(stringValue: "gegrLat", intValue: nil)], debugDescription: "Expected to decode Double but found a string/data instead.", underlyingError: nil))
            }
        }.resume()
    }
}

The API response is array of objects, its look like: response example So i want to display list of this object in my application.

I would be really gratefull for any help

Change your "Station" structure so gegrLon and gegrLat are Strings:

struct Station: Codable {
    var id: Int
    var stationName: String
    var gegrLat: String
    var gegrLon: String
    var city: City
    var addressStreet: String?
}

ie your error is saying that is Expected to decode Double but found a string/data instead.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM