无法读取数据,因为它的格式不正确(swift)

Posted

技术标签:

【中文标题】无法读取数据,因为它的格式不正确(swift)【英文标题】:The data couldn’t be read because it isn’t in the correct format (swift) 【发布时间】:2020-06-30 23:28:37 【问题描述】:

我想用 JSON 获取天气信息,但出现错误:无法读取数据,因为它的格式不正确。

错误'看起来您的帖子主要是代码;请添加更多细节。在堆栈溢出中。虽然我简要描述了我的问题,但它仍然希望我能给出解释:/

override func viewDidLoad() 
            super.viewDidLoad()
            let url = "https://api.openweathermap.org/data/2.5/weather?q=bursa,tr&appid=00f63a1cff271776651468c0204c422c"
            getData(from: url)
        
        
        private func getData (from url : String)
           let task = URLSession.shared.dataTask(with: URL(string: url)!, completionHandler:  data , response , error in
                guard let data = data ,  error == nil else 
                    print ("birşeyler ters gitti")
                    return
                
            var main : Response?
                do 
                    main = try JSONDecoder().decode(Response.self , from: data)
                 catch
                    print ("ERROR IS HERE!!! \(error.localizedDescription)")
                
                guard let json = main else 
                    return
                
            print (json.weather)
                )
            task.resume()
        
        
        
    
        
    struct Response : Codable 
               let weather : myResult
               let status : String
               
           
    struct myResult : Codable 
               let main : String
               let description : String
               let icon : String
           

API 响应是这样的:

"coord":  "lon": 139,"lat": 35,
  "weather": [
    
      "id": 800,
      "main": "Clear",
      "description": "clear sky",
      "icon": "01n"
    
  ],
  "base": "stations",
  "main": 
    "temp": 281.52,
    "feels_like": 278.99,
    "temp_min": 280.15,
    "temp_max": 283.71,
    "pressure": 1016,
    "humidity": 93
  ,
  "wind": 
    "speed": 0.47,
    "deg": 107.538
  ,
  "clouds": 
    "all": 2
  ,
  "dt": 1560350192,
  "sys": 
    "type": 3,
    "id": 2019346,
    "message": 0.0065,
    "country": "JP",
    "sunrise": 1560281377,
    "sunset": 1560333478
  ,
  "timezone": 32400,
  "id": 1851632,
  "name": "Shuzenji",
  "cod": 200

【问题讨论】:

catch 块中将error.localizedDescription 替换为error。现在您会收到有关解码错误的有意义的错误消息。 @vadian 我已经准备好将它包含在我的答案中。不知何故,我只是忘了更新它。谢谢提醒:) 【参考方案1】:

首先,error.localizedDescription 旨在为用户显示信息。它对调试没有用。如果换成error:

 catch 
    print ("ERROR IS HERE!!! \(error)") // <- remove .localizedDescription

您将获得更多详细信息:

错误在这里!!! typeMismatch(Swift.Dictionary, Swift.DecodingError.Context(codingPath: [CodingKeys(stringValue: "天气", intValue: nil)], debugDescription: "预计解码 Dictionary 但找到了一个数组。”,基础错误: 无))

要解决这个问题,您需要将weather 声明为一个数组:

let weather: [myResult]

我还建议将myResult 替换为Weather(或至少大写MyResult),因为这样更易读:

struct Weather: Codable 
    let main: String
    let description: String
    let icon: String

此外,在您提供的 JSON 响应中,没有 status 字段,因此您可能需要将其从 Response 类中删除(或使其成为可选)。

如果您想在响应中添加更多字段,请根据您的 JSON 结构声明它们。例如。如果你想添加humiditytemperature 你可以这样做:

struct Response: Codable 
    ...
    let main: Main


struct Main: Codable 
    let temp: Double
    let humidity: Double

要获得更易读的代码,您可以使用CodingKeys - 然后您的变量名可以独立于 JSON 变量。

struct Main: Codable 
    enum CodingKeys: String, CodingKey 
        case temperature = "temp"
        case humidity
    
    
    let temperature: Double
    let humidity: Double

总结一下,您的Response 可能如下所示:

struct Response: Codable 
    let weather: [Weather]
    let main: Main
    // alternatively declare `status` optional
    // let status: String?


struct Weather: Codable 
    let main: String
    let description: String
    let icon: String


struct Main: Codable 
    enum CodingKeys: String, CodingKey 
        case temperature = "temp"
        case humidity
    
    
    let temperature: Double
    let humidity: Double

【讨论】:

谢谢...现在我们的结果是 [Hava_Durumu.myResult(main: "Clear", description: "clear sky", icon: "01n")]。我怎样才能达到“主要”或“描述”?打印(json.weather.main)不工作 @E.YILDIRIM weather 是一个数组(元素的集合),这意味着您需要访问特定元素。例如。如果你想访问天气数组中的第一个元素,你可以使用:json.weather[0].main 那么如何添加湿度和温度值?它给出了这样的错误:数据无法读取,因为它丢失了。 @E.YILDIRIM 查看我的更新答案 - 删除 .localizedDescription,您将获得更多详细信息。

以上是关于无法读取数据,因为它的格式不正确(swift)的主要内容,如果未能解决你的问题,请参考以下文章

Swift 中的 JSON 解码。无法读取数据,因为它的格式不正确

Swift/MySql/PHP - “无法读取数据,因为它的格式不正确。”错误

Swift iOS Intent 扩展:无法读取数据,因为它的格式不正确

在 Swift 4 中使用新的 JSONDecoder 协议时,我得到“无法读取数据,因为它的格式不正确。”错误

错误是无法读取数据,因为它的格式不正确

无法读取数据,因为它的格式不正确 Xcode 11