【问题标题】:Fetching and parsing JSON获取和解析 JSON
【发布时间】:2021-02-22 11:43:18
【问题描述】:

我很难获取和解析以下 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()
    }

【问题讨论】:

  • 输出是什么?
  • 你的数据模型car没有反映json结构。
  • 由于cars 不是字符串,所以不会解析
  • 您的 JSON 格式不正确。它包含不匹配的引号、不匹配的“[”和不匹配的“{”字符。

标签: ios json swift parsing decodable


【解决方案1】:

您的 Car 模型不代表您的 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

【讨论】:

  • 谢谢伙计。这似乎有效。由于类型不匹配,我不得不将“self.cars = try decoder.decode(Car.self, from: data)”替换为“let data = try decoder.decode(Car.self, from: data)”。现在需要弄清楚如何提取响应。
【解决方案2】:

如果您要使用 Codable 协议和JSONDecoder(),您将需要创建一个与您的 JSON 格式匹配的结构。正如其他人在他们的 cmets 中指出的那样,您的 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
        }
    ]
}

(为了便于阅读,我添加了空格。它不会影响解析。)

【讨论】:

    猜你喜欢
    • 2016-05-09
    • 2012-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-20
    • 1970-01-01
    • 1970-01-01
    • 2016-09-10
    相关资源
    最近更新 更多