简体   繁体   English

Swift:JSONDecoder 从 API 返回 nil

[英]Swift: JSONDecoder returning nil from API

currently working through an app that gets and decodes data from OpenWeatherMap API, currently I've got everything working except getting the decoder to return something.目前正在通过一个从 OpenWeatherMap API 获取和解码数据的应用程序工作,目前我已经完成了所有工作,除了让解码器返回一些东西。 Currently, the decoder is returning nil, however, I am getting bytes of data from the API call.目前,解码器正在返回 nil,但是,我正在从 API 调用中获取数据字节。 I am not exactly sure what could be the issue.我不确定可能是什么问题。 I've got the ViewModel struct set up in terms of hierarchy.我已经根据层次结构设置了 ViewModel 结构。 The OPW API JSON data seems to be in the format of a dictionary key:value pair collection type, keys are enclosed in quotes, could it be that my decoder isn't finding the necessary information because of the quotation marks? OPW API JSON 数据好像是字典key:value pair collection类型的格式,key用引号括起来,会不会是我的解码器因为引号没有找到必要的信息?

Getting and Decoding the API call...获取和解码 API 呼叫...

@IBAction func saveCityButtonPressed() {

    if let city = cityNameTextField.text {
        let weatherURL = URL(string: "https://api.openweathermap.org/data/2.5/weather?q=\(city)&APPID=8bad8461edbaf3ff50aa2f2fd8ad8a71&units=imperial")!

        let weatherResource = Resource<WeatherViewModel>(url: weatherURL) { data in
            let weatherVM = try? JSONDecoder().decode(WeatherViewModel.self, from: data)
            return weatherVM
        }
        Webservice().load(resource: weatherResource) { result in
        }
    }
}

ViewModel视图模型

struct WeatherListViewModel {
private var weatherViewModels = [WeatherViewModel]()
}

struct WeatherViewModel: Decodable {
let name: String
let main: TemperatureViewModel
}

struct TemperatureViewModel: Decodable {
let temp: Double
let temp_min: Double
let temp_max: Double
}

Example of JSON data: JSON数据示例:

{
    "coord":{
       "lon":-0.13,
       "lat":51.51
    },
    "weather":[
        {
             "id":300,
             "main":"Drizzle",
             "description":"light intensity drizzle","icon":"09d"
        }
    ],
    "base":"stations",
    "main":{
        "temp":280.32,
        "pressure":1012,
        "humidity":81,
        "temp_min":279.15,
        "temp_max":281.15
     },
     "visibility":10000,
     "wind":{
         "speed":4.1,
         "deg":80
     },
     "clouds":{
         "all":90
     },
     "dt":1485789600,
     "sys":{
         "type":1,
         "id":5091,
         "message":0.0103,
         "country":"GB",
         "sunrise":1485762037,
         "sunset":1485794875
     },
     "id":2643743,
     "name":"London",
     "cod":200
 }

By making the result of JSONDecoder().decode an optional ( try? ), you are ensuring that you get nil if the decoding goes wrong.通过将JSONDecoder().decode的结果JSONDecoder().decode可选( try? ),您可以确保在解码出错时得到nil You can catch decoding related issues quickly by implementing proper catch blocks.您可以通过实施适当的 catch 块来快速捕获与解码相关的问题。 Eg:例如:

do {
    let decoder = JSONDecoder()
    let messages = try decoder.decode(WeatherViewModel.self, from: data)
    print(messages as Any)
} catch DecodingError.dataCorrupted(let context) {
    print(context)
} catch DecodingError.keyNotFound(let key, let context) {
    print("Key '\(key)' not found:", context.debugDescription)
    print("codingPath:", context.codingPath)
} catch DecodingError.valueNotFound(let value, let context) {
    print("Value '\(value)' not found:", context.debugDescription)
    print("codingPath:", context.codingPath)
} catch DecodingError.typeMismatch(let type, let context) {
    print("Type '\(type)' mismatch:", context.debugDescription)
    print("codingPath:", context.codingPath)
} catch {
    print("error: ", error)
}

Not a direct answer to your question, but surely will reduce other's time to understand which part of decoding is going wrong.不是对您问题的直接回答,但肯定会减少其他人了解解码哪一部分出错的时间。

您的 WeatherViewModel 属性city是一个字符串,但您的 JSON 中没有"city"键。

Why do we get nil value, when decoding the value?为什么我们在解码值时得到 nil 值?

Reasons:原因:
The response parameter may be the first letter as capital.响应参数可以是首字母大写。

Solution:解决方案:
The coding keys concept is to out to nil value.编码键的概念是输出到零值。

Example:例子:

struct Example{
var a: string
var b: string

enum Codingkeys: String,CodingKey{
case a = "a"
case b = "b"
}
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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