获取和解析 JSON

Fetching and parsing JSON

我很难获取和解析以下 JSON。我什至无法从给定的 url 中获取数据,更不用说使用我的数据模型“Car”来解析它了。我们非常欢迎任何帮助!

JSON

{
   "cars":[
      {
         "date_stolen":1604616183,
         "description":null,
         "body_colors":[
            "Black",
            "Blue"
         ],
         "id":"944846",
         "is_stock_img":false,
         "large_img":null,
         "location_found":null,
         "manufacturer_name":"Toyota",
         "external_id":null,
         "registry_name":null,
         "registry_url":null,
         "serial":"36-17-01012-xl09",
         "status":null,
         "stolen":true,
         "stolen_location":"Calgary - CA",
         "thumb":null,
         "title":"2017 Toyota Corolla ",
         "url":"https://cars.org/944846",
         "year":2017
      }
   ]
}
struct Car: Decodable {
        let cars: String
    }
var cars = [Car]()
fileprivate func fetchJSON() {
        let urlString = "someUrl…"
        guard let url = URL(string: urlString) else { return }
        URLSession.shared.dataTask(with: url) { (data, _, err) in
            DispatchQueue.main.async {
                if let err = err {
                    print("Failed to get data from url:", err)
                    return
                }
                
                guard let data = data else { return }
                
                do {
                    
                    let decoder = JSONDecoder()
                    
                    decoder.keyDecodingStrategy = .convertFromSnakeCase

                    print("DATA \n", data)
                    self.cars = try decoder.decode(Car.self, from: data)
                    
                    print("---> ", data)
                    
                } catch let jsonErr {
                    print("Failed to decode:", jsonErr)
                }
            }
        }.resume()
    }

你的车型不代表你json结构。

您正在寻找这样的东西:

struct CarsResponse: Decodable {
    let cars: [CarDTO]
}

struct CarDTO: Decodable {
    let id: String
    let isStockImg: Bool
    // And so on
}

然后写:

let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let carResponse = try decoder.decode(CarsResponse.self, from: data)

您可以通过写

来访问您的汽车
let cars: [CarDTO] = carResponse.cars

如果您要使用 Codable 协议并且 JSONDecoder() 您将需要创建一个与您的 JSON 格式相匹配的结构。正如其他人在评论中指出的那样,您的 Car 结构与您接收的数据格式完全不同。

如果您只想将接收到的 JSON 反序列化到包含值的字典中,您可以改用 JSONSerialization。

为此,您可以用如下代码替换 do 块的主体:

let object = try JSONSerialization.jsonObject(with: data, options: []) 

然后您必须自己浏览 object 的字典结构。它不像创建自定义结构和使用 Codable 那样简洁,但它确实有效。

请注意,您的 JSON 中存在语法错误。这是清理后的版本:

{"cars":
    [
        {"date_stolen":1604616183,
            "description":null,
            "body_colors":["Black","Blue"],
            "id":944846,
            "is_stock_img":false,
            "large_img":null,
            "location_found":null,
            "manufacturer_name":"Toyota",
            "external_id":null,
            "registry_name":null,
            "registry_url":null,
            "serial":"36-17-01012-xl09",
            "status":null,
            "stolen":true,
            "stolen_location":"Calgary - CA",
            "thumb":null,
            "title":"2017 Toyota Corolla ",
            "url":"https://cars.org/944846",
            "year":2017
        }
    ]
}

(我添加了空格以提高可读性。它不会影响任何一种解析方式。)