Как разобрать JSON в Swift с помощью JSON .serializer - PullRequest
2 голосов
/ 03 апреля 2020

Я учился анализировать OpenWeather API в XCode и немного запутался. Поэтому я должен сделать запрос на получение отчета о погоде от OpenWeather, а затем отобразить его на этикетках, которые я подготовил.

У меня есть основной V C с выводами этикеток

class ViewController: UIViewController { 
   @IBOutlet weak var weatherDescriptionlabel: UILabel!
   @IBOutlet weak var cityLabel: UILabel!
   @IBOutlet weak var currentWeatherLabel: UILabel!

   var Data: [DataClass] = []
   var cityName: String = ""
   var currentWeather: Int = 0
   var weatherDescription: String = ""

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        dataLoader().loadData()
    }
}

У меня есть отдельный класс для "подготовки" JSON данных для передачи

class WeatherDataClass {

let cityName: String
let currentWeather: Int
let weatherDescription: String

init (data: NSDictionary){
    let cityName = data["name"] as? String
    let currentWeather = data["temp"] as? String
    let weatherDescription = data["description"] as? String
    self.cityName = cityName!
    self.currentWeather = Int(currentWeather!)!
    self.weatherDescription = weatherDescription!
}
}

и DataLoader, который вызывает API

protocol dataLoaderDelegate{
    func load( data: [WeatherDataClass] ) }

class dataLoader{

    var delegate: dataLoaderDelegate?

    var Url = URL(string: "http://api.openweathermap.org/data/2.5/weather?q=London,uk&APPID=f2a7ca3bd41dfa2efab0ad667aafe1df")!

    func loadData(){

        let url = Url
        let request = URLRequest(url: url)
        let task = URLSession.shared.dataTask(with: request) { data, response, error in
            if let data = data,
                let json = try? JSONSerialization.jsonObject(with: data, options: .allowFragments),
            let jsonDict = json as? NSDictionary{
                var weather: [WeatherDataClass] = []
                for (_,data) in jsonDict where data is NSDictionary{
                    if let x = WeatherDataClass(data: data as! NSDictionary){
                        weather.append(x)
                    }
                }
                self.delegate?.load(data: weather)

            } }
        task.resume()


    }
}

Проблема в том, что данные из JSONdict не Обернуть в NSDictionary Он остается Any и дает мне ошибку

Что я делаю не так? Заранее спасибо за помощь

Ответы [ 2 ]

0 голосов
/ 03 апреля 2020

После проверки вашего запроса я бы предложил использовать JSONDecoder и Кодируемый протокол.

Вы должны начать с создания своих структур и утешить Кодируемый протокол:

struct Coord: Codable {
    var lon: Double
    var lat: Double
}

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

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

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

struct Clouds: Codable {
    let all: Int
}

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

struct WeatherQuery: 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 timezone: Int
    let id: Int
    let name: String
    let cod: Int
}

После этого вы можете сделать следующее:

let request = URLRequest(url: URL(string: "http://api.openweathermap.org/data/2.5/weather?q=London,uk&APPID=f2a7ca3bd41dfa2efab0ad667aafe1df")!)

let task = URLSession.shared.dataTask(with: request) { data, response, error in
    guard let data = data else { return }
    let decoder = JSONDecoder()
    decoder.keyDecodingStrategy = .convertFromSnakeCase

    do {
        let weatherQuery = try decoder.decode(WeatherQuery.self, from: data)
        ...
    } catch {
        print("[DEBUG] Error is here - \(error)")
    }
}

task.resume()
0 голосов
/ 03 апреля 2020

Проверьте ниже ... Ниже приведены все данные, которые поступают из открытого API погоды. настроить как вы будете sh.

let task = URLSession.shared.dataTask(with: request) {
    (data, response, error) in

    //If data did return and is not nil
    if let dataReturned = data {

        //If let json
        if let json = try? JSONSerialization.jsonObject(with: dataReturned, options: .allowFragments) as? NSDictionary {

            //print("**** WEATHER JSON **** = \(json)")

            //Date Formatter
            let dateFormatter = DateFormatter()
            dateFormatter.dateFormat = "HH:mm"

            //Picking Apart JSON
            let locationName = json["name"] as? String
            let visibility = json["visibility"] as? Int
            let mainInformation = json["main"] as? NSDictionary
            let weatherInArray = json["weather"] as? NSArray
            let coords = json["coord"] as? NSDictionary
            let system = json["sys"] as? NSDictionary
            let wind = json["wind"] as? NSDictionary
            let weather = weatherInArray?[0] as? NSDictionary

            //Main Information
            let temp = mainInformation?.value(forKey: "temp") as? Double
            let humidity = mainInformation?.value(forKey: "humidity") as? Int
            let pressure = mainInformation?.value(forKey: "pressure") as? Int
            let roundedTemp = Int(round(temp ?? 0.00))

            //Weather Information
            let weatherDiscription = weather?.value(forKey: "description") as? String
            let weatherID = weather?.value(forKey: "id") as? Int

            //Coords Information
            let longitude = coords?.value(forKey: "lon") as? Double
            let latitude = coords?.value(forKey: "lat") as? Double

            //System Information
            let sunrise = system?.value(forKey: "sunrise") as? Int
            let sunriseTwo = Double(sunrise ?? 0)
            let dateSunrise = NSDate(timeIntervalSince1970: sunriseTwo)
            let sunriseTime = dateFormatter.string(from: dateSunrise as Date)

            let sunset = system?.value(forKey: "sunset") as? Int
            let sunsetTwo = Double(sunset ?? 0)
            let dateSunset = NSDate(timeIntervalSince1970: sunsetTwo)
            let sunsetTime = dateFormatter.string(from: dateSunset as Date)

            //Wind Information
            let windSpeed = wind?.value(forKey: "speed") as? Double
            let windAngle = wind?.value(forKey: "deg") as? Double

            //APPEND TO YOUR ARRAY HERE
            Your_Array_Here = Your_Array_here.append(WeatherDataClass(cityName: ***  , currentWeather: ***, weatherDescription: *** ))



        }

    }

}

task.resume()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...