Значение строки и значок погоды в OpenWeatherMap - PullRequest
0 голосов
/ 25 апреля 2019

Я пытаюсь получить значение Main и Description из значения, но оно не отображается в UILabel. Все остальные параметры хорошо видны. Как температура и максимальная и минимальная температура Скорость и направление ветра. У меня также возникают проблемы с иконкой погоды, и мне нужен совет, если мой код правильный

import UIKit
import Foundation

class ViewController: UIViewController {
    var timer = Timer()

    struct CurrentLocalWeather: Codable {
        let base: String
        let clouds: Clouds
        let cod: Int
        let coord: Coord
        let dt: Int
        let id: Int
        let main: Main
        let name: String
        let sys: Sys
        let visibility: Int
        let weather: Weather
        let wind: Wind
    }

    struct Clouds: Codable {
        let all: Int
    }

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

    struct Main: Codable {
        let humidity: Int
        let pressure: Int
        let temp: Double
        let tempMax: Double
        let tempMin: Double
        private enum CodingKeys: String, CodingKey {
            case humidity, pressure, temp, tempMax = "temp_max", tempMin = "temp_min"
        }
    }

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

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

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

    //Variables from Storyboard
    @IBOutlet weak var Temp: UILabel!
    @IBOutlet weak var TempMin: UILabel!
    @IBOutlet weak var TempMax: UILabel!
    @IBOutlet weak var WindSpeed: UILabel!
    @IBOutlet weak var Direction: UILabel!
    @IBOutlet weak var Humidity: UILabel!
    @IBOutlet weak var MainDesc: UILabel!
    @IBOutlet weak var Description: UILabel!
    @IBOutlet weak var City: UILabel!
    @IBOutlet weak var SunRise: UILabel!
    @IBOutlet weak var SunSet: UILabel!
    @IBOutlet weak var Icon: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Define URL for Weather Data
        URLSession.shared.dataTask(with: URL(string: "https://api.openweathermap.org/data/2.5/weather?lat=51.05011&lon=-114.08529&appid=<APPID_REMOVED_FOR_POSTING_PURPOSE>&units=metric")!) { data, response, error in
            if let error = error {
                print("Error:\n\(error)")
            } else {
                do {
                    let JSon = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! [String: AnyObject]

                    if let Temp1 = JSon["weather"]as? NSDictionary {
                        DispatchQueue.main.async {
                            self.Description.text = Temp1["description"] as? String
                            self.MainDesc.text = Temp1["main"] as? String
                        let Ico = (Temp1["icon"] as? String)!
                            let Icon = UIImageView()
                            let urlStr = NSURL(string:"http://openweathermap.org/img/w/\(Ico).png")
                            let urlData = NSData(contentsOf: urlStr! as URL)
                            if urlData == nil {
                                Icon.image = UIImage(data: urlData! as Data)
                            }
                        }
                    }
} catch let jsonError as NSError {
                    print("JSON error:\n\(jsonError.description)")
                }
            }
            }.resume()
}

Это результат запроса:

{"ordin ": {" lon ": - 114.09," lat ": 51.05}," погода ": [{" id ": 802," main ":" Облака "," описание ":" рассеянные облака " "значок": "03d"}], "база": "станции", "главный": { "темп": 10,9, "давление": 1014, "влажность": 32, "temp_min": 8,89," temp_max ": 13,33}," видимость ": 56326," ветер ": {" скорость ": 11,3," град ": 20}," облака ": {" все ": 40}," дт ": 1556142366," SYS ": {" тип ": 1," идентификатор ": 989," сообщение ": 0,0068," страна ":" CA " "восход": 1556108578, "закат": 1556160342}, "идентификатор": 5913490," имя ":" Калгари», "треск": 200}

Ответы [ 2 ]

0 голосов
/ 01 мая 2019

Это довольно просто с Decodable.

Это структуры, в которых пропущены ненужные клавиши

struct CurrentLocalWeather: Decodable {
    let main: Main
    let name: String
    let sys: Sys
    let weather: [Weather]
    let wind: Wind
}

struct Main: Decodable {
    let humidity: Int
    let temp: Double
    let tempMin, tempMax: Double
}

struct Sys: Decodable {
    let sunrise: Date
    let sunset: Date
}

struct Weather: Decodable {
    let description: String
    let icon: String
    let main: String
}

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

Чтобы получить значок, вам нужно второе задание данных, получениесинхронные данные - это очень плохая практика.

И несоответствие правилам именования в отношении чувствительности к регистру тоже очень плохая практика.

class ViewController: UIViewController {
    var timer = Timer()


    //Variables from Storyboard
    @IBOutlet weak var temp: UILabel!
    @IBOutlet weak var tempMin: UILabel!
    @IBOutlet weak var tempMax: UILabel!
    @IBOutlet weak var windSpeed: UILabel!
    @IBOutlet weak var direction: UILabel!
    @IBOutlet weak var humidity: UILabel!
    @IBOutlet weak var mainDesc: UILabel!
    @IBOutlet weak var desc: UILabel!
    @IBOutlet weak var city: UILabel!
    @IBOutlet weak var sunrise: UILabel!
    @IBOutlet weak var sunset: UILabel!
    @IBOutlet weak var icon: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Define URL for Weather Data
        URLSession.shared.dataTask(with: URL(string: "https://api.openweathermap.org/data/2.5/weather?lat=51.05011&lon=-114.08529&appid=<APPID_REMOVED_FOR_POSTING_PURPOSE>&units=metric")!) { data, response, error in
           guard let data = data else {  print("Error:", error!); return }
            do {
               let decoder = JSONDecoder()
               decoder.keyDecodingStrategy = .convertFromSnakeCase
               decoder.dateDecodingStrategy = .secondsSince1970
               let result = try decoder.decode(CurrentLocalWeather.self, from: data)
               guard let weather = result.weather.first else { return }
               DispatchQueue.main.async {
                    self.desc.text = weather.description
                    self.mainDesc.text = weather.main
                    let icon = weather.icon
                    URLSession.shared.dataTask(with: URL(string: "http://openweathermap.org/img/w/\(icon).png")!) { iconData, _ , _ in
                       if let data = iconData {
                          DispatchQueue.main.async {
                             self.icon.image = UIImage(data: data)
                          }
                       }
                    }.resume()
               }
            } catch {
                print("JSON error:", error)
            }
       }.resume()
    }
}
0 голосов
/ 01 мая 2019

Мне удалось решить проблему с не отображаемым строковым значением, внеся указанные ниже изменения.

Import UIKit
import Foundation

class ViewController: UIViewController {
    var timer = Timer()


    //Variables from Storyboard
    @IBOutlet weak var Temp: UILabel!
    @IBOutlet weak var TempMin: UILabel!
    @IBOutlet weak var TempMax: UILabel!
    @IBOutlet weak var WindSpeed: UILabel!
    @IBOutlet weak var Direction: UILabel!
    @IBOutlet weak var Humidity: UILabel!
    @IBOutlet weak var MainDesc: UILabel!
    @IBOutlet weak var Description: UILabel!
    @IBOutlet weak var City: UILabel!
    @IBOutlet weak var SunRise: UILabel!
    @IBOutlet weak var SunSet: UILabel!
    @IBOutlet weak var Icon: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Define URL for Weather Data
        URLSession.shared.dataTask(with: URL(string: "https://api.openweathermap.org/data/2.5/weather?lat=51.05011&lon=-114.08529&appid=<APPID_REMOVED_FOR_POSTING_PURPOSE>&units=metric")!) { data, response, error in
            if let error = error {
                print("Error:\n\(error)")
            } else {
                do {
                    let JSon = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! [String: AnyObject]

                    let weatherData = (JSon["weather"]as! NSArray)
                    if let Temp1 = weatherData[0] as? NSDictionary {
                        DispatchQueue.main.async {
                            self.Description.text = Temp1["description"] as? String
                            self.MainDesc.text = Temp1["main"] as? String
                        let Ico = (Temp1["icon"] as? String)!
                            let urlStr = NSURL(string:"http://openweathermap.org/img/w/\(Ico).png")
                            let urlData = NSData(contentsOf: urlStr! as URL)
                            if urlData != nil {
                                self.Icon.image = UIImage(data: urlData! as Data)
                            }
                        }
                    }
} catch let jsonError as NSError {
                    print("JSON error:\n\(jsonError.description)")
                }
            }
            }.resume()
}

Я все еще не могу заставить работать иконку, надеюсь, я тоже смогу опубликовать это.для тех, кто пытался использовать Codable и правильно понял, пожалуйста, поделитесь.

...