SwiftUI - не удалось отобразить jsonData - PullRequest
0 голосов
/ 05 мая 2020

Я новичок в SwiftUi, и я пытаюсь просмотреть данные json, и в настоящее время я работаю над получением данных о погоде с openweathermap.org, который представляет собой бесплатный API для получения текущей погоды. Я получаю сообщение Ошибка при синтаксическом анализе погоды Json. Я не уверен, что делаю не так !! Любая помощь будет принята с благодарностью, и я застрял на этом в течение дня. Я сослался на множество блогов и руководств о том, как использовать Опубликованные var и ObservableObject. Я не могу решить проблему.

This is my swift file


struct WeatherData {
    public var Id: Int
    public var main: String
    public var weather: [Weather]
    public var icon: String
}

extension WeatherData: Decodable, Identifiable {
    var id: Int {return Id}
}


struct WeatherView: View {
    @ObservedObject var fetch = FetchWeather()

    var body: some View {
        VStack {
            List(fetch.weatherData) {
                wthr in
                VStack(alignment: .leading){
                    Text("\(wthr.id)")
                    Text("\(wthr.weather[0].description)")
                    Text("\(wthr.icon)")
                        .font(.system(size:11))
                        .foregroundColor(Color.gray)
                }
            }
        }
    }
}

struct Weather: Decodable {
    let description: String
}

struct WeatherView_Previews: PreviewProvider {
    static var previews: some View {
        WeatherView()
    }
}


class FetchWeather: ObservableObject {
    @Published var weatherData = [WeatherData] ()

    init() {
        load()
    }

    func load() {
        let url = URL(string: "https://api.openweathermap.org/data/2.5/weather?q=London&appid=myapikey")!


        URLSession.shared.dataTask(with: url) {
            (data, response, error) in
            do {
                if let wthData = data {
                    let decodedData = try JSONDecoder().decode([WeatherData].self, from: wthData)
                    DispatchQueue.main.sync {
                        self.weatherData = decodedData
                    }
                }
                else {
                    print("No json Data available")
                }
            }catch {
                print("Error parsing Weather Json")
            }
        }.resume()
    }
}

1 Ответ

1 голос
/ 05 мая 2020

Попробуйте этот код. Я подписался на получение api и соответственно исправил Model, ViewModel и View. Я не добавил загрузчик изображений для строк значков.

import SwiftUI

struct Weather: Decodable{
    var description: String
    var icon :String
}

struct MainData: Decodable {
    var temp: Double
    var pressure: Int
    var humidity: Int
    var temp_min: Double
    var temp_max: Double

}

struct WeatherData: Decodable, Identifiable {
    var id: Int
    var main: MainData
    var weather: [Weather]
    var name: String
}

struct WeatherView: View {
    @ObservedObject var fetch = FetchWeather()

    var body: some View {
        VStack(alignment: .leading) {
            Text("Current Weather").font(.title).padding()
            List(fetch.weatherData) { wthr in
                HStack {
                    VStack(alignment: .leading){
                        Text("\(wthr.name)")
                        Text("\(wthr.weather[0].description)")
                            .font(.system(size:11))
                            .foregroundColor(Color.gray)
                    }
                    Spacer()
                    VStack(alignment: .trailing){
                        Text("\(wthr.main.temp-273.15, specifier: "%.1f") ºC")
                    }
                    Text("\(wthr.weather[0].icon)") // Image from "https://openweathermap.org/img/w/\(wthr.weather[0].icon).png"
                        .foregroundColor(Color.gray)
                }
            }
        }
    }
}

class FetchWeather: ObservableObject {
    @Published var weatherData = [WeatherData]()

    private let baseURL = "https://api.openweathermap.org/data/2.5/weather?q="
    private let cities = [ "London", "Mumbai", "New+york", "Vatican+City" ]
    private let api = "&appid="+"e44ebeb18c332fff46ab956bb38f9e07"

    init() {
        for city in self.cities {
            self.load(self.baseURL+city+self.api)
        }
    }

    func load(_ urlString: String) {
        if let url = URL(string: urlString) {
            URLSession.shared.dataTask(with: url) { (data, response, error) in
                do {
                    if let wthData = data {
                        let decodedData = try JSONDecoder().decode(WeatherData.self, from: wthData)
                        DispatchQueue.main.sync {
                            self.weatherData.append(decodedData)
                        }
                    }
                    else {
                        print("No json Data available")
                    }
                } catch let error as NSError{
                    print(error.localizedDescription)
                }
            }.resume()
        } else {
            print("Unable to decode URL")
        }
    }
}
...