首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >keyNotFound(CodingKeys(stringValue:"coord",intValue:无)

keyNotFound(CodingKeys(stringValue:"coord",intValue:无)
EN

Stack Overflow用户
提问于 2019-04-28 22:39:16
回答 1查看 2.4K关注 0票数 -1

我正在使用openweatherAPI构建一个小的快速天气应用程序,我在尝试解析JSON时遇到了一些问题。我使用了以下函数来解析get和json。

下面是我的天气数据结构:

代码语言:javascript
复制
struct WeatherData: Codable {
    let coord: Coord
    let weather: [Weather]
    let base: String
    let main: Main
    let visibility: Int
    let wind: Wind
    let clouds: Clouds
    let dt: Int
    let sys: Sys
    let id: Int
    let name: String
    let cod: Int
}

struct Clouds: Codable {
    let all: Int
}

struct Coord: Codable {
    let lon, lat: Double
}

struct Main: Codable {
    let temp: Double
    let pressure, humidity: Int
    let tempMin, tempMax: Double

    enum CodingKeys: String, CodingKey {
        case temp, pressure, humidity
        case tempMin = "temp_min"
        case tempMax = "temp_max"
    }
}

struct Sys: Codable {
    let type, id: Int
    let message: Double
    let country: String
    let sunrise, sunset: Int
}

struct Weather: Codable {
    let id: Int
    let main, description, icon: String
}

struct Wind: Codable {
    let speed: Double
    let deg: Int
}


private func getWeatherData(url: String, parameters: [String : String]) {
    let JsonURLString:[String: Any] = ["url": WEATHER_URL, "parameters": parameters]
    print(JsonURLString)
    let urlString = JsonURLString["url"] as? String
    guard let url = URL(string: urlString!) else { return }
    URLSession.shared.dataTask(with: url) { ( data, response, err ) in
        DispatchQueue.main.sync {
            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
                let city = try decoder.decode(WeatherData.self, from: data)
                self.weatherData.description = city.weather[0].description
                self.weatherData.temperature = Int(city.main.temp - 273)
                self.weatherData.city = city.name
                self.weatherData.condition = city.weather[0].id
                self.updateUIWeatherData()
            } catch {
                print(error)
                self.cityLabel.text = "Connection issues"
            }
        }
    }.resume()
}

我得到的确切错误如下:

代码语言:javascript
复制
  longitude = -0.1337, latitude = 51.50998
 ["parameters": ["lat": "51.50998", "long": "-0.1337", "appid":    "xxxxxxxxxxxxxxxxxx"], "url":   "https://api.openweathermap.org/data/2.5/weather"]
  keyNotFound(CodingKeys(stringValue: "coord", intValue: nil),    Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated     with key CodingKeys(stringValue: \"coord\", intValue: nil) (\"coord\").",    underlyingError: nil))

我看过下面的example,并不知道这是如何应用的。任何帮助都将不胜感激。

图标未出现。这是我的模型:

代码语言:javascript
复制
import UIKit

class WeatherDataModel {

//Declare your model variables here
var temperature: Int = 0
var condition: Int = 0
var city: String = ""
var weatherIconName = ""
var description: String = ""

//This method turns a condition code into the name of the weather condition image

func updateWeatherIcon(condition: Int) -> String {

switch (condition) {

    case 0...300 :
        return "tstorm1"

    case 301...500 :
        return "light_rain"

    case 501...600 :
        return "shower3"

    case 601...700 :
        return "snow4"

    case 701...771 :
        return "fog"

    case 772...799 :
        return "tstorm3"

    case 800 :
        return "sunny"

    case 801...804 :
        return "cloudy2"

    case 900...903, 905...1000  :
        return "tstorm3"

    case 903 :
        return "snow5"

    case 904 :
        return "sunny"

    default :
        return "dunno"
    }

   }
 }

我已经添加了我自己的图标。我已经在do catch块中添加了这个。

代码语言:javascript
复制
do {
                let decoder = JSONDecoder()
                decoder.keyDecodingStrategy = .convertFromSnakeCase
                let city = try decoder.decode(WeatherData.self, from: data)
                print(city)
                self.weatherData.description = city.weather[0].description
                self.weatherData.temperature = Int(city.main.temp - 273)
                self.weatherData.city = city.name
                self.weatherData.condition = city.weather[0].id
                self.weatherData.weatherIconName = WeatherDataModel.updateWeatherIcon(self.weatherData.condition)
                self.updateUIWeatherData()
            } catch {
                print(error)
                self.cityLabel.text = "Connection issues"
            }

我现在得到的错误是:

代码语言:javascript
复制
Instance member 'updateWeatherIcon' cannot be used on type 'WeatherDataModel'; did you mean to use a value of this type instead?
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-04-28 23:03:50

您只创建了openweathermap地址,但忽略了参数。

使用类似下面的内容,例如URLComponentsURLQueryItem来正确构建URL查询。

代码语言:javascript
复制
private func getWeatherData(parameters: [String : String]) {
    guard let lat = parameters["lat"], 
          let long = parameters["long"],
          let appID = parameters["appid"] else { print("Invalid parameters"); return } 
    var urlComponents = URLComponents(string: "https://api.openweathermap.org/data/2.5/weather")!
    let queryItems = [URLQueryItem(name: "lat", value: lat),
                      URLQueryItem(name: "lon", value: long),
                      URLQueryItem(name: "appid", value: appID)]
    urlComponents.queryItems = queryItems

    guard let url = urlComponents.url else { return }
    URLSession.shared.dataTask(with: url) { ( data, response, err ) in
        DispatchQueue.main.async { // never, never, never sync !!
            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
                let city = try decoder.decode(WeatherData.self, from: data)
                print(city)
                self.weatherData.description = city.weather[0].description
                self.weatherData.temperature = Int(city.main.temp - 273)
                self.weatherData.city = city.name
                self.weatherData.condition = city.weather[0].id
                self.updateUIWeatherData()
            } catch {
                print(error)
                self.cityLabel.text = "Connection issues"
            }
        }
        }.resume()
}

并且只通过

代码语言:javascript
复制
["lat": "51.50998", "long": "-0.1337", "appid": "xxxxxxxxxxxxxxxxxx"]

作为参数。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55891354

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档