keyNotFound error when parsing OpenWeather JSON da

2020-05-03 13:31发布

问题:

I need to retrieve the "name" object by using openWeather API, and I manage to parse json and retrieve the data, but for its particular objects such as "name" I constantly receiving this error:

keyNotFound(CodingKeys(stringValue: "name", intValue: nil), Swift.DecodingError.Context(codingPath: [], debugDescription: "No value associated with key CodingKeys(stringValue: \"name\", intValue: nil) (\"name\").", underlyingError: nil))

Need help to solve this issue. Thanks.

This is my code(in 3 Files):

//----------------------WeatherBrain File------------------------------

import Foundation
import SwiftUI

class ClimaBrain : ObservableObject {
    @Published var textFieldValue = ""
    @Published var urlString = ""
    @Published var weatherURL = "https://api.openweathermap.org/data/2.5/find?APPID=03c40ac21db250c8d1ce3aba0bf32c89&q="


    func performRequest(urlString: String){
        if let url = URL(string: urlString){
            let session = URLSession(configuration: .default)
            let task = session.dataTask(with: url) { (data, response, error) in
                if error != nil{
                    print(error!)
                    return
                }
                if let safeData = data{
                    self.parseJSON(weatherData: safeData)

                }
            }
            task.resume()
        }
    }


    func parseJSON(weatherData : Data){
        let decoder = JSONDecoder()
        do{
            let decodedData = try decoder.decode(WeatherData.self, from: weatherData)
            print("Brain Parse Data: \(decodedData.name)")
        } catch{
            print(error)
        }
    }


    func fetchWeather()  {
        urlString = "\(weatherURL)\(textFieldValue)&units=metric&"
        performRequest(urlString: urlString)
    }


    func endEditing() {
        UIApplication.shared.endEditing()
        self.fetchWeather()
    }

}


//----------------------WeatherData File------------------------------

import Foundation

struct WeatherData: Decodable {
    let name : String
    let main: Main
}


struct Main: Decodable {
    let temp: Double
}


//----------------------ContentView File------------------------------

import Foundation
import SwiftUI

struct ContentView: View {

    @ObservedObject var climaBrain = ClimaBrain()

    var body: some View {
        ZStack{
            Image("light_background")
                .resizable()
                .scaledToFill()
                .edgesIgnoringSafeArea(.all)
            VStack{
                HStack{

                    TextField("Search", text: $climaBrain.textFieldValue){
                        self.climaBrain.endEditing()
                        print("Return Key:  \(self.climaBrain.urlString)")
                    }
                    .keyboardType(.default)
                    .font(Font.custom("Halvetica", size: 30))
                    .frame(width: 200, height: 60, alignment: .center)
                    .padding(10)
                    VStack{
                        Button(action: {
                            self.climaBrain.endEditing()
                            print("Icon Button: \(self.climaBrain.urlString)")
                        }) {
                            Image(systemName: "magnifyingglass")
                                .renderingMode(.original)
                                .resizable()
                                .scaledToFit()
                                .frame(width: 50, height: 50, alignment: .center)
                        }
                    }
                }
            }
        }
    }
}

回答1:

You are expecting a WeatherData object to contain 2 fields: name and main. But apparently, the actual data doesn't contain name. You need to double check the actual data you're trying to parse and update you WeatherData model.